react-native-ota-hot-update 1.0.8 → 1.1.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.
- package/README.md +13 -9
- package/android/src/main/java/com/rnhotupdate/HotUpdateModule.java +4 -4
- package/ios/RNhotupdate.m +7 -7
- package/package.json +1 -2
- package/src/download.d.ts +860 -0
- package/src/index.tsx +21 -20
package/README.md
CHANGED
|
@@ -78,9 +78,10 @@ After you have done everything related to version manager, you just handle the w
|
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
80
|
import hotUpdate from 'react-native-ota-hot-update';
|
|
81
|
+
import ReactNativeBlobUtil from 'react-native-blob-util';
|
|
81
82
|
|
|
82
83
|
|
|
83
|
-
hotUpdate.downloadBundleUri(url, version, {
|
|
84
|
+
hotUpdate.downloadBundleUri(ReactNativeBlobUtil, url, version, {
|
|
84
85
|
updateSuccess: () => {
|
|
85
86
|
console.log('update success!');
|
|
86
87
|
},
|
|
@@ -102,14 +103,14 @@ The important thing: this library will control `version` by it self, need always
|
|
|
102
103
|
|
|
103
104
|
## Functions
|
|
104
105
|
|
|
105
|
-
| key | Return | Action | Parameters
|
|
106
|
-
| ------------
|
|
107
|
-
| downloadBundleUri | void | Download bundle and install it | (uri: string, version: number, option?: **UpdateOption**)
|
|
108
|
-
| setupBundlePath | boolean | Install your bundle path if you control the downloading by your self, ignore that if you use `downloadBundleUri` | path: string, the path of bundlejs file that you downloaded before
|
|
109
|
-
| removeUpdate | void | Remove you update and use the previos version | restartAfterRemoved?: boolean, restart to apply your changing
|
|
110
|
-
| resetApp | void | Restart the app to apply the changing | empty
|
|
111
|
-
| getCurrentVersion | number | Get the current version that let you use to compare and control the logic updating | empty
|
|
112
|
-
| setCurrentVersion | boolean | Set the current version that let you use to compare and control the logic updating | version: number
|
|
106
|
+
| key | Return | Action | Parameters |
|
|
107
|
+
| ------------ |--------|------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|
|
|
108
|
+
| downloadBundleUri | void | Download bundle and install it | (downloadManager: **DownloadManager**, uri: string, version: number, option?: **UpdateOption**) |
|
|
109
|
+
| setupBundlePath | boolean | Install your bundle path if you control the downloading by your self, ignore that if you use `downloadBundleUri` | path: string, the path of bundlejs file that you downloaded before |
|
|
110
|
+
| removeUpdate | void | Remove you update and use the previos version | restartAfterRemoved?: boolean, restart to apply your changing |
|
|
111
|
+
| resetApp | void | Restart the app to apply the changing | empty |
|
|
112
|
+
| getCurrentVersion | number | Get the current version that let you use to compare and control the logic updating | empty |
|
|
113
|
+
| setCurrentVersion | boolean | Set the current version that let you use to compare and control the logic updating | version: number |
|
|
113
114
|
|
|
114
115
|
|
|
115
116
|
## UpdateOption
|
|
@@ -121,8 +122,11 @@ The important thing: this library will control `version` by it self, need always
|
|
|
121
122
|
| updateFail(message: string) | No | Callback | Will trigger when install update failed |
|
|
122
123
|
| restartAfterInstall | No | boolean | default is `false`, if `true` will restart the app after install success to apply the new change |
|
|
123
124
|
| progress | No | void | A callback to show progress when downloading bundle |
|
|
125
|
+
| extensionBundle | No | string | extension of bundle js file, default is .bundle, for expo project you might set .hbc |
|
|
124
126
|
|
|
127
|
+
## DownloadManager
|
|
125
128
|
|
|
129
|
+
The same method as `react-native-blob-util` or `rn-fetch-blob`
|
|
126
130
|
|
|
127
131
|
## License
|
|
128
132
|
|
|
@@ -50,7 +50,7 @@ public class HotUpdateModule extends ReactContextBaseJavaModule {
|
|
|
50
50
|
return false;
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
private String unzip(File zipFile) {
|
|
53
|
+
private String unzip(File zipFile, String extension) {
|
|
54
54
|
File destDir = zipFile.getParentFile(); // Directory of the zip file
|
|
55
55
|
|
|
56
56
|
String bundleFilePath = null;
|
|
@@ -78,7 +78,7 @@ public class HotUpdateModule extends ReactContextBaseJavaModule {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
if (newFile.getAbsolutePath().contains(
|
|
81
|
+
if (newFile.getAbsolutePath().contains(extension)) {
|
|
82
82
|
bundleFilePath = newFile.getAbsolutePath();
|
|
83
83
|
}
|
|
84
84
|
}
|
|
@@ -90,12 +90,12 @@ public class HotUpdateModule extends ReactContextBaseJavaModule {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
@ReactMethod
|
|
93
|
-
public void setupBundlePath(String path, Promise promise) {
|
|
93
|
+
public void setupBundlePath(String path, String extension, Promise promise) {
|
|
94
94
|
if (path != null) {
|
|
95
95
|
deleteOldBundleIfneeded();
|
|
96
96
|
File file = new File(path);
|
|
97
97
|
if (file.exists() && file.isFile()) {
|
|
98
|
-
String fileUnzip = unzip(file);
|
|
98
|
+
String fileUnzip = unzip(file, extension != null ? extension : ".bundle");
|
|
99
99
|
Log.d("setupBundlePath: ", fileUnzip);
|
|
100
100
|
if (fileUnzip != null) {
|
|
101
101
|
file.delete();
|
package/ios/RNhotupdate.m
CHANGED
|
@@ -97,7 +97,7 @@ RCT_EXPORT_MODULE()
|
|
|
97
97
|
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
- (NSString *)searchForJsBundleInDirectory:(NSString *)directoryPath {
|
|
100
|
+
- (NSString *)searchForJsBundleInDirectory:(NSString *)directoryPath extension:(NSString *)extension {
|
|
101
101
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
102
102
|
NSError *error;
|
|
103
103
|
|
|
@@ -114,11 +114,11 @@ RCT_EXPORT_MODULE()
|
|
|
114
114
|
if ([fileManager fileExistsAtPath:filePath isDirectory:&isDirectory]) {
|
|
115
115
|
if (isDirectory) {
|
|
116
116
|
// Recursively search in subdirectories
|
|
117
|
-
NSString *foundPath = [self searchForJsBundleInDirectory:filePath];
|
|
117
|
+
NSString *foundPath = [self searchForJsBundleInDirectory:filePath extension:extension];
|
|
118
118
|
if (foundPath) {
|
|
119
119
|
return foundPath;
|
|
120
120
|
}
|
|
121
|
-
} else if ([filePath hasSuffix
|
|
121
|
+
} else if ([filePath hasSuffix:extension]) {
|
|
122
122
|
// Return the path if it's a .jsbundle file
|
|
123
123
|
return filePath;
|
|
124
124
|
}
|
|
@@ -127,7 +127,7 @@ RCT_EXPORT_MODULE()
|
|
|
127
127
|
|
|
128
128
|
return nil;
|
|
129
129
|
}
|
|
130
|
-
- (NSString *)unzipFileAtPath:(NSString *)zipFilePath {
|
|
130
|
+
- (NSString *)unzipFileAtPath:(NSString *)zipFilePath extension:(NSString *)extension {
|
|
131
131
|
// Define the directory where the files will be extracted
|
|
132
132
|
NSString *extractedFolderPath = [[zipFilePath stringByDeletingPathExtension] stringByAppendingPathExtension:@"unzip"];
|
|
133
133
|
|
|
@@ -151,7 +151,7 @@ RCT_EXPORT_MODULE()
|
|
|
151
151
|
return nil;
|
|
152
152
|
}
|
|
153
153
|
// Find .jsbundle files in the extracted directory
|
|
154
|
-
|
|
154
|
+
NSString *jsbundleFilePath = [self searchForJsBundleInDirectory:extractedFolderPath extension:extension];
|
|
155
155
|
|
|
156
156
|
// Delete the zip file after extraction
|
|
157
157
|
NSError *removeError = nil;
|
|
@@ -165,11 +165,11 @@ RCT_EXPORT_MODULE()
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
// Expose setupBundlePath method to JavaScript
|
|
168
|
-
RCT_EXPORT_METHOD(setupBundlePath:(NSString *)path withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) {
|
|
168
|
+
RCT_EXPORT_METHOD(setupBundlePath:(NSString *)path extension:(NSString *)extension withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) {
|
|
169
169
|
if ([self isFilePathValid:path]) {
|
|
170
170
|
[self removeBundleIfNeeded];
|
|
171
171
|
//Unzip file
|
|
172
|
-
NSString *extractedFilePath = [self unzipFileAtPath:path];
|
|
172
|
+
NSString *extractedFilePath = [self unzipFileAtPath:path extension:(extension != nil) ? extension : @".jsbundle"];
|
|
173
173
|
NSLog(@"file extraction----- %@", extractedFilePath);
|
|
174
174
|
if (extractedFilePath) {
|
|
175
175
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-ota-hot-update",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Hot update for react native",
|
|
5
5
|
"main": "src/index",
|
|
6
6
|
"repository": "https://github.com/vantuan88291/react-native-ota-hot-update",
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
},
|
|
12
12
|
"homepage": "https://github.com/vantuan88291/react-native-ota-hot-update",
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"react-native-blob-util": ">=0.19.11",
|
|
15
14
|
"react-native": ">=0.63.4"
|
|
16
15
|
},
|
|
17
16
|
"create-react-native-library": {
|
|
@@ -0,0 +1,860 @@
|
|
|
1
|
+
|
|
2
|
+
interface DownloadManager {
|
|
3
|
+
fetch(method: Methods, url: string, headers?: { [key: string]: string }, body?: any | null): StatefulPromise<FetchBlobResponse>;
|
|
4
|
+
|
|
5
|
+
base64: { encode(input: string): string; decode(input: string): string };
|
|
6
|
+
android: AndroidApi;
|
|
7
|
+
ios: IOSApi;
|
|
8
|
+
|
|
9
|
+
config(options: ReactNativeBlobUtilConfig): DownloadManager;
|
|
10
|
+
|
|
11
|
+
session(name: string): ReactNativeBlobUtilSession;
|
|
12
|
+
|
|
13
|
+
fs: FS;
|
|
14
|
+
MediaCollection: MediaCollection;
|
|
15
|
+
|
|
16
|
+
wrap(path: string): string;
|
|
17
|
+
|
|
18
|
+
net: Net;
|
|
19
|
+
polyfill: Polyfill;
|
|
20
|
+
// this require external module https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/oboe
|
|
21
|
+
JSONStream: any;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface Polyfill {
|
|
25
|
+
Blob: PolyfillBlob;
|
|
26
|
+
File: PolyfillFile;
|
|
27
|
+
XMLHttpRequest: PolyfillXMLHttpRequest;
|
|
28
|
+
ProgressEvent: PolyfillProgressEvent;
|
|
29
|
+
Event: PolyfillEvent;
|
|
30
|
+
FileReader: PolyfillFileReader;
|
|
31
|
+
Fetch: PolyfillFetch;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export declare class PolyfillFetch extends ReactNativeBlobUtilFetchPolyfill {
|
|
35
|
+
constructor(config: ReactNativeBlobUtilConfig);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export declare class ReactNativeBlobUtilFetchPolyfill {
|
|
39
|
+
constructor(config: ReactNativeBlobUtilConfig);
|
|
40
|
+
|
|
41
|
+
build(): (url: string, options: ReactNativeBlobUtilConfig) => StatefulPromise<ReactNativeBlobUtilFetchRepsonse>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface ReactNativeBlobUtilFetchRepsonse {
|
|
45
|
+
arrayBuffer(): Promise<any[]>;
|
|
46
|
+
|
|
47
|
+
blob(): Promise<PolyfillBlob>;
|
|
48
|
+
|
|
49
|
+
json(): Promise<any>;
|
|
50
|
+
|
|
51
|
+
rawResp(): Promise<FetchBlobResponse>;
|
|
52
|
+
|
|
53
|
+
text(): Promise<string>;
|
|
54
|
+
|
|
55
|
+
bodyUsed: boolean;
|
|
56
|
+
headers: any;
|
|
57
|
+
ok: boolean;
|
|
58
|
+
resp: FetchBlobResponse;
|
|
59
|
+
rnfbResp: FetchBlobResponse;
|
|
60
|
+
rnfbRespInfo: ReactNativeBlobUtilResponseInfo;
|
|
61
|
+
status: number;
|
|
62
|
+
type: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* ReactNativeBlobUtil response object class.
|
|
67
|
+
*/
|
|
68
|
+
export interface FetchBlobResponse {
|
|
69
|
+
taskId: string;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* get path of response temp file
|
|
73
|
+
* @return File path of temp file.
|
|
74
|
+
*/
|
|
75
|
+
path(): string;
|
|
76
|
+
|
|
77
|
+
type: "base64" | "path" | "utf8";
|
|
78
|
+
data: any;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Convert result to javascript ReactNativeBlobUtil object.
|
|
82
|
+
* @return Return a promise resolves Blob object.
|
|
83
|
+
*/
|
|
84
|
+
blob(contentType: string, sliceSize: number): Promise<PolyfillBlob>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Convert result to text.
|
|
88
|
+
* @return Decoded base64 string.
|
|
89
|
+
*/
|
|
90
|
+
text(): string | Promise<any>;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Convert result to JSON object.
|
|
94
|
+
* @return Parsed javascript object.
|
|
95
|
+
*/
|
|
96
|
+
json(): any;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Return BASE64 string directly.
|
|
100
|
+
* @return BASE64 string of response body.
|
|
101
|
+
*/
|
|
102
|
+
base64(): any;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Remove cahced file
|
|
106
|
+
*/
|
|
107
|
+
flush(): void;
|
|
108
|
+
|
|
109
|
+
respInfo: ReactNativeBlobUtilResponseInfo;
|
|
110
|
+
|
|
111
|
+
info(): ReactNativeBlobUtilResponseInfo;
|
|
112
|
+
|
|
113
|
+
session(name: string): ReactNativeBlobUtilSession | null;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Read file content with given encoding, if the response does not contains
|
|
117
|
+
* a file path, show warning message
|
|
118
|
+
* @param encode Encode type, should be one of `base64`, `ascrii`, `utf8`.
|
|
119
|
+
*/
|
|
120
|
+
readFile(encode: Encoding): Promise<any> | null;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Start read stream from cached file
|
|
124
|
+
* @param encode Encode type, should be one of `base64`, `ascrii`, `utf8`.
|
|
125
|
+
*/
|
|
126
|
+
readStream(encode: Encoding): ReactNativeBlobUtilStream | null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface PolyfillFileReader extends EventTarget {
|
|
130
|
+
isRNFBPolyFill: boolean;
|
|
131
|
+
|
|
132
|
+
onloadstart(e: Event): void;
|
|
133
|
+
|
|
134
|
+
onprogress(e: Event): void;
|
|
135
|
+
|
|
136
|
+
onload(e: Event): void;
|
|
137
|
+
|
|
138
|
+
onabort(e: Event): void;
|
|
139
|
+
|
|
140
|
+
onerror(e: Event): void;
|
|
141
|
+
|
|
142
|
+
onloadend(e: Event): void;
|
|
143
|
+
|
|
144
|
+
abort(): void;
|
|
145
|
+
|
|
146
|
+
readAsArrayBuffer(b: PolyfillBlob): void;
|
|
147
|
+
|
|
148
|
+
readAsBinaryString(b: PolyfillBlob): void;
|
|
149
|
+
|
|
150
|
+
readAsText(b: PolyfillBlob, label?: string): void;
|
|
151
|
+
|
|
152
|
+
readAsDataURL(b: PolyfillBlob): void;
|
|
153
|
+
|
|
154
|
+
readyState: number;
|
|
155
|
+
result: number;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export declare namespace PolyfillFileReader {
|
|
159
|
+
const EMPTY: number;
|
|
160
|
+
const LOADING: number;
|
|
161
|
+
const DONE: number;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export declare class PolyfillEvent {}
|
|
165
|
+
|
|
166
|
+
export interface PolyfillProgressEvent extends EventTarget {
|
|
167
|
+
lengthComputable: boolean;
|
|
168
|
+
loaded: number;
|
|
169
|
+
total: number;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export declare class PolyfillBlob implements EventTarget {
|
|
173
|
+
/**
|
|
174
|
+
* ReactNativeBlobUtil Blob polyfill, create a Blob directly from file path, BASE64
|
|
175
|
+
* encoded data, and string. The conversion is done implicitly according to
|
|
176
|
+
* given `mime`. However, the blob creation is asynchronously, to register
|
|
177
|
+
* event `onCreated` is need to ensure the Blob is creadted.
|
|
178
|
+
*
|
|
179
|
+
* @param data Content of Blob object
|
|
180
|
+
* @param cType Content type settings of Blob object, `text/plain` by default
|
|
181
|
+
* @param defer When this argument set to `true`, blob constructor will not invoke blob created event automatically.
|
|
182
|
+
*/
|
|
183
|
+
constructor(data: any, cType: any, defer: boolean);
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Since Blob content will asynchronously write to a file during creation,
|
|
187
|
+
* use this method to register an event handler for Blob initialized event.
|
|
188
|
+
* @param fn An event handler invoked when Blob created
|
|
189
|
+
* @return The Blob object instance itself
|
|
190
|
+
*/
|
|
191
|
+
onCreated(fn: () => void): PolyfillBlob;
|
|
192
|
+
|
|
193
|
+
markAsDerived(): void;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Get file reference of the Blob object.
|
|
197
|
+
* @return Blob file reference which can be consumed by ReactNativeBlobUtil fs
|
|
198
|
+
*/
|
|
199
|
+
getReactNativeBlobUtilRef(): string;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Create a Blob object which is sliced from current object
|
|
203
|
+
* @param start Start byte number
|
|
204
|
+
* @param end End byte number
|
|
205
|
+
* @param contentType Optional, content type of new Blob object
|
|
206
|
+
*/
|
|
207
|
+
slice(start?: number, end?: number, contentType?: string): PolyfillBlob;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Read data of the Blob object, this is not standard method.
|
|
211
|
+
* @param encoding Read data with encoding
|
|
212
|
+
*/
|
|
213
|
+
readBlob(encoding: string): Promise<any>;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Release the resource of the Blob object.
|
|
217
|
+
* @nonstandard
|
|
218
|
+
*/
|
|
219
|
+
close(): Promise<void>;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export declare namespace PolyfillBlob {
|
|
223
|
+
function clearCache(): void;
|
|
224
|
+
|
|
225
|
+
function build(data: any, cType: any): Promise<PolyfillBlob>;
|
|
226
|
+
|
|
227
|
+
function setLog(level: number): void;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export declare class PolyfillFile extends PolyfillBlob {}
|
|
231
|
+
|
|
232
|
+
export interface PolyfillXMLHttpRequest extends PolyfillXMLHttpRequestEventTarget {
|
|
233
|
+
upload: PolyfillXMLHttpRequestEventTarget;
|
|
234
|
+
readonly UNSENT: number;
|
|
235
|
+
readonly OPENED: number;
|
|
236
|
+
readonly HEADERS_RECEIVED: number;
|
|
237
|
+
readonly LOADING: number;
|
|
238
|
+
readonly DONE: number;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* XMLHttpRequest.open, always async, user and password not supported. When
|
|
242
|
+
* this method invoked, headers should becomes empty again.
|
|
243
|
+
* @param method Request method
|
|
244
|
+
* @param url Request URL
|
|
245
|
+
* @param async Always async
|
|
246
|
+
* @param user NOT SUPPORTED
|
|
247
|
+
* @param password NOT SUPPORTED
|
|
248
|
+
*/
|
|
249
|
+
open(method: string, url: string, async: true, user: any, password: any): void;
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Invoke this function to send HTTP request, and set body.
|
|
253
|
+
* @param body Body in ReactNativeBlobUtil flavor
|
|
254
|
+
*/
|
|
255
|
+
send(body: any): void;
|
|
256
|
+
|
|
257
|
+
overrideMimeType(mime: string): void;
|
|
258
|
+
|
|
259
|
+
setRequestHeader(name: string, value: string): void;
|
|
260
|
+
|
|
261
|
+
abort(): void;
|
|
262
|
+
|
|
263
|
+
getResponseHeader(field: string): string | null;
|
|
264
|
+
|
|
265
|
+
getAllResponseHeaders(): string | null;
|
|
266
|
+
|
|
267
|
+
onreadystatechange(e: Event): void;
|
|
268
|
+
|
|
269
|
+
readyState: number;
|
|
270
|
+
status: number;
|
|
271
|
+
statusText: string;
|
|
272
|
+
response: any;
|
|
273
|
+
responseText: any;
|
|
274
|
+
responseURL: string;
|
|
275
|
+
responseHeaders: any;
|
|
276
|
+
timeout: number;
|
|
277
|
+
responseType: string;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export declare namespace PolyfillXMLHttpRequest {
|
|
281
|
+
const binaryContentTypes: string[];
|
|
282
|
+
const UNSENT: number;
|
|
283
|
+
const OPENED: number;
|
|
284
|
+
const HEADERS_RECEIVED: number;
|
|
285
|
+
const LOADING: number;
|
|
286
|
+
const DONE: number;
|
|
287
|
+
|
|
288
|
+
function setLog(level: number): void;
|
|
289
|
+
|
|
290
|
+
function addBinaryContentType(substr: string): void;
|
|
291
|
+
|
|
292
|
+
function removeBinaryContentType(): void;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export interface PolyfillXMLHttpRequestEventTarget extends EventTarget {
|
|
296
|
+
onabort(e: Event): void;
|
|
297
|
+
|
|
298
|
+
onerror(e: Event): void;
|
|
299
|
+
|
|
300
|
+
onload(e: Event): void;
|
|
301
|
+
|
|
302
|
+
onloadstart(e: Event): void;
|
|
303
|
+
|
|
304
|
+
onprogress(e: Event): void;
|
|
305
|
+
|
|
306
|
+
ontimeout(e: Event): void;
|
|
307
|
+
|
|
308
|
+
onloadend(e: Event): void;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export interface Net {
|
|
312
|
+
/**
|
|
313
|
+
* Get cookie according to the given url.
|
|
314
|
+
* @param domain Domain of the cookies to be removed, remove all
|
|
315
|
+
* @return Cookies of a specific domain.
|
|
316
|
+
*/
|
|
317
|
+
getCookies(domain: string): Promise<string[]>;
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Remove cookies for a specific domain
|
|
321
|
+
* @param domain Domain of the cookies to be removed, remove all
|
|
322
|
+
* cookies when this is null.
|
|
323
|
+
*/
|
|
324
|
+
removeCookies(domain?: string): Promise<null>;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
type HashAlgorithm = "md5" | "sha1" | "sha224" | "sha256" | "sha384" | "sha512";
|
|
328
|
+
|
|
329
|
+
export interface FS {
|
|
330
|
+
ReactNativeBlobUtilSession: ReactNativeBlobUtilSession;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Remove file at path.
|
|
334
|
+
* @param path:string Path of target file.
|
|
335
|
+
*/
|
|
336
|
+
unlink(path: string): Promise<void>;
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Create a directory.
|
|
340
|
+
* @param path Path of directory to be created
|
|
341
|
+
*/
|
|
342
|
+
mkdir(path: string): Promise<void>;
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Get a file cache session
|
|
346
|
+
* @param name Stream ID
|
|
347
|
+
*/
|
|
348
|
+
session(name: string): ReactNativeBlobUtilSession;
|
|
349
|
+
|
|
350
|
+
ls(path: string): Promise<string[]>;
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Read the file from the given path and calculate a cryptographic hash sum over its contents.
|
|
354
|
+
*
|
|
355
|
+
* @param path Path to the file
|
|
356
|
+
* @param algorithm The hash algorithm to use
|
|
357
|
+
*/
|
|
358
|
+
hash(path: string, algorithm: HashAlgorithm): Promise<string>;
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Create file stream from file at `path`.
|
|
362
|
+
* @param path The file path.
|
|
363
|
+
* @param encoding Data encoding, should be one of `base64`, `utf8`, `ascii`
|
|
364
|
+
* @param bufferSize Size of stream buffer.
|
|
365
|
+
* @return ReactNativeBlobUtilStream stream instance.
|
|
366
|
+
*/
|
|
367
|
+
readStream(path: string, encoding: Encoding, bufferSize?: number, tick?: number): Promise<ReactNativeBlobUtilReadStream>;
|
|
368
|
+
|
|
369
|
+
mv(path: string, dest: string): Promise<boolean>;
|
|
370
|
+
|
|
371
|
+
cp(path: string, dest: string): Promise<boolean>;
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Create write stream to a file.
|
|
375
|
+
* @param path Target path of file stream.
|
|
376
|
+
* @param encoding Encoding of input data.
|
|
377
|
+
* @param append A flag represent if data append to existing ones.
|
|
378
|
+
* @return A promise resolves a `WriteStream` object.
|
|
379
|
+
*/
|
|
380
|
+
writeStream(path: string, encoding: Encoding, append?: boolean): Promise<ReactNativeBlobUtilWriteStream>;
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Write data to file.
|
|
384
|
+
* @param path Path of the file.
|
|
385
|
+
* @param data Data to write to the file.
|
|
386
|
+
* @param encoding Encoding of data (Optional).
|
|
387
|
+
*/
|
|
388
|
+
writeFile(path: string, data: string | number[], encoding?: Encoding): Promise<void>;
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Processes the data and then writes to the file.
|
|
392
|
+
* @param path Path of the file.
|
|
393
|
+
* @param data Data to write to the file.
|
|
394
|
+
* @param encoding Encoding of data (Optional).
|
|
395
|
+
*/
|
|
396
|
+
writeFileWithTransform(path: string, data: string | number[], encoding?: Encoding): Promise<void>;
|
|
397
|
+
|
|
398
|
+
appendFile(path: string, data: string | number[], encoding?: Encoding | "uri"): Promise<number>;
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Wrapper method of readStream.
|
|
402
|
+
* @param path Path of the file.
|
|
403
|
+
* @param encoding Encoding of read stream.
|
|
404
|
+
*/
|
|
405
|
+
readFile(path: string, encoding: Encoding, bufferSize?: number): Promise<any>;
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Reads from a file and then processes the data before returning
|
|
409
|
+
* @param path Path of the file.
|
|
410
|
+
* @param encoding Encoding of read stream.
|
|
411
|
+
*/
|
|
412
|
+
readFileWithTransform(path: string, encoding: Encoding, bufferSize?: number): Promise<any>;
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Check if file exists and if it is a folder.
|
|
416
|
+
* @param path Path to check
|
|
417
|
+
*/
|
|
418
|
+
exists(path: string): Promise<boolean>;
|
|
419
|
+
|
|
420
|
+
createFile(path: string, data: string, encoding: Encoding): Promise<void>;
|
|
421
|
+
|
|
422
|
+
isDir(path: string): Promise<boolean>;
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Show statistic data of a path.
|
|
426
|
+
* @param path Target path
|
|
427
|
+
*/
|
|
428
|
+
stat(path: string): Promise<ReactNativeBlobUtilStat>;
|
|
429
|
+
|
|
430
|
+
lstat(path: string): Promise<ReactNativeBlobUtilStat[]>;
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Android only method, request media scanner to scan the file.
|
|
434
|
+
* @param pairs Array contains Key value pairs with key `path` and `mime`.
|
|
435
|
+
*/
|
|
436
|
+
scanFile(pairs: Array<{ [key: string]: string }>): Promise<void>;
|
|
437
|
+
|
|
438
|
+
dirs: Dirs;
|
|
439
|
+
|
|
440
|
+
slice(src: string, dest: string, start: number, end: number): Promise<void>;
|
|
441
|
+
|
|
442
|
+
asset(path: string): string;
|
|
443
|
+
|
|
444
|
+
df(): Promise<RNFetchBlobDf>;
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Returns the path for the app group.
|
|
448
|
+
* @param {string} groupName Name of app group
|
|
449
|
+
*/
|
|
450
|
+
pathForAppGroup(groupName: string): Promise<string>;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
export interface RNFetchBlobDfIOS {
|
|
454
|
+
free?: number;
|
|
455
|
+
total?: number;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
export interface RNFetchBlobDfAndroid {
|
|
459
|
+
external_free?: string;
|
|
460
|
+
external_total?: string;
|
|
461
|
+
internal_free?: string;
|
|
462
|
+
internal_total?: string;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
export type RNFetchBlobDf = RNFetchBlobDfIOS & RNFetchBlobDfAndroid;
|
|
466
|
+
|
|
467
|
+
export interface Dirs {
|
|
468
|
+
DocumentDir: string;
|
|
469
|
+
CacheDir: string;
|
|
470
|
+
PictureDir: string;
|
|
471
|
+
LibraryDir: string;
|
|
472
|
+
MusicDir: string;
|
|
473
|
+
MovieDir: string;
|
|
474
|
+
DownloadDir: string;
|
|
475
|
+
DCIMDir: string;
|
|
476
|
+
SDCardDir: string;
|
|
477
|
+
MainBundleDir: string;
|
|
478
|
+
|
|
479
|
+
LegacyPictureDir: string;
|
|
480
|
+
LegacyMusicDir: string;
|
|
481
|
+
LegacyMovieDir: string;
|
|
482
|
+
LegacyDownloadDir: string;
|
|
483
|
+
LegacyDCIMDir: string;
|
|
484
|
+
LegacySDCardDir: string; // Depracated
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
export interface ReactNativeBlobUtilWriteStream {
|
|
488
|
+
id: string;
|
|
489
|
+
encoding: string;
|
|
490
|
+
append: boolean;
|
|
491
|
+
|
|
492
|
+
write(data: string): Promise<void>;
|
|
493
|
+
|
|
494
|
+
close(): Promise<void>;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
export interface ReactNativeBlobUtilReadStream {
|
|
498
|
+
path: string;
|
|
499
|
+
encoding: Encoding;
|
|
500
|
+
bufferSize?: number;
|
|
501
|
+
closed: boolean;
|
|
502
|
+
tick: number;
|
|
503
|
+
|
|
504
|
+
open(): void;
|
|
505
|
+
|
|
506
|
+
onData(fn: (chunk: string | number[]) => void): void;
|
|
507
|
+
|
|
508
|
+
onError(fn: (err: any) => void): void;
|
|
509
|
+
|
|
510
|
+
onEnd(fn: () => void): void;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
export type Encoding = "utf8" | "ascii" | "base64";
|
|
514
|
+
|
|
515
|
+
/* tslint:disable-next-line interface-name*/
|
|
516
|
+
export interface IOSApi {
|
|
517
|
+
/**
|
|
518
|
+
* Open a file in {@link https://developer.apple.com/reference/uikit/uidocumentinteractioncontroller UIDocumentInteractionController},
|
|
519
|
+
* this is the default document viewer of iOS, supports several kinds of files. On Android, there's an similar method {@link android.actionViewIntent}.
|
|
520
|
+
* @param path This is a required field, the path to the document. The path should NOT contain any scheme prefix.
|
|
521
|
+
* @param {string} scheme URI scheme that needs to support, optional
|
|
522
|
+
*/
|
|
523
|
+
previewDocument(path: string, scheme?: string): void;
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Show options menu for interact with the file.
|
|
527
|
+
* @param path This is a required field, the path to the document. The path should NOT contain any scheme prefix.
|
|
528
|
+
* @param {string} scheme URI scheme that needs to support, optional
|
|
529
|
+
*/
|
|
530
|
+
openDocument(path: string, scheme?: string): Promise<void>;
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Displays an options menu using [UIDocumentInteractionController](https://developer.apple.com/reference/uikit/uidocumentinteractioncontroller).[presentOptionsMenu](https://developer.apple.com/documentation/uikit/uidocumentinteractioncontroller/1616814-presentoptionsmenu)
|
|
534
|
+
* @param {string} path Path of the file to be open.
|
|
535
|
+
* @param {string} scheme URI scheme that needs to support, optional
|
|
536
|
+
*/
|
|
537
|
+
presentOptionsMenu(path: string, scheme?: string): void;
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Displays a menu for opening the document using [UIDocumentInteractionController](https://developer.apple.com/reference/uikit/uidocumentinteractioncontroller).[presentOpenInMenu](https://developer.apple.com/documentation/uikit/uidocumentinteractioncontroller/1616807-presentopeninmenu)
|
|
541
|
+
* @param {string} path Path of the file to be open.
|
|
542
|
+
* @param {string} scheme URI scheme that needs to support, optional
|
|
543
|
+
*/
|
|
544
|
+
presentOpenInMenu(path: string, scheme?: string): void;
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Displays a full-screen preview of the target document using [UIDocumentInteractionController](https://developer.apple.com/reference/uikit/uidocumentinteractioncontroller).[presentPreview](https://developer.apple.com/documentation/uikit/uidocumentinteractioncontroller/1616828-presentpreview)
|
|
548
|
+
* @param {string} path Path of the file to be open.
|
|
549
|
+
* @param {string} scheme URI scheme that needs to support, optional
|
|
550
|
+
*/
|
|
551
|
+
presentPreview(path: string, scheme?: string): void;
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Marks the file to be excluded from icloud/itunes backup. Works recursively if path is to a directory
|
|
555
|
+
* @param {string} path Path to a file or directory to mark to be excluded.
|
|
556
|
+
*/
|
|
557
|
+
excludeFromBackupKey(path: string): Promise<void>;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
export interface AndroidDownloadOption {
|
|
561
|
+
/**
|
|
562
|
+
* Title string to be displayed when the file added to Downloads app.
|
|
563
|
+
*/
|
|
564
|
+
title: string;
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* File description to be displayed when the file added to Downloads app.
|
|
568
|
+
*/
|
|
569
|
+
description: string;
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* MIME string of the file.
|
|
573
|
+
*/
|
|
574
|
+
mime: string;
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* URI string of the file.
|
|
578
|
+
*/
|
|
579
|
+
path: string;
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* Boolean value that determines if notification will be displayed.
|
|
583
|
+
*/
|
|
584
|
+
showNotification: boolean;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
export interface AndroidApi {
|
|
588
|
+
/**
|
|
589
|
+
* When sending an ACTION_VIEW intent with given file path and MIME type, system will try to open an
|
|
590
|
+
* App to handle the file. For example, open Gallery app to view an image, or install APK.
|
|
591
|
+
* @param path Path of the file to be opened.
|
|
592
|
+
* @param mime Basically system will open an app according to this MIME type.
|
|
593
|
+
* @param chooserTitle title for chooser, if not set the chooser won't be displayed (see [Android docs](https://developer.android.com/reference/android/content/Intent.html#createChooser(android.content.Intent,%20java.lang.CharSequence)))
|
|
594
|
+
*/
|
|
595
|
+
actionViewIntent(path: string, mime: string, chooserTitle?: string): Promise<boolean | null>;
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
*
|
|
599
|
+
* This method brings up OS default file picker and resolves a file URI when the user selected a file.
|
|
600
|
+
* However, it does not resolve or reject when user dismiss the file picker via pressing hardware back button,
|
|
601
|
+
* but you can still handle this behavior via AppState.
|
|
602
|
+
* @param mime MIME type filter, only the files matches the MIME will be shown.
|
|
603
|
+
*/
|
|
604
|
+
getContentIntent(mime: string): Promise<any>;
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Using this function to add an existing file to Downloads app.
|
|
608
|
+
* @param options An object that for setting the title, description, mime, and notification of the item.
|
|
609
|
+
*/
|
|
610
|
+
addCompleteDownload(options: AndroidDownloadOption): Promise<void>;
|
|
611
|
+
|
|
612
|
+
getSDCardDir(): Promise<string>;
|
|
613
|
+
|
|
614
|
+
getSDCardApplicationDir(): Promise<string>;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
type Methods = "POST" | "GET" | "DELETE" | "PUT" | "PATCH" | "post" | "get" | "delete" | "put" | "patch";
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* A declare class inherits Promise, it has extra method like progress, uploadProgress,
|
|
621
|
+
* and cancel which can help managing an asynchronous task's state.
|
|
622
|
+
*/
|
|
623
|
+
export interface StatefulPromise<T> extends Promise<T> {
|
|
624
|
+
/**
|
|
625
|
+
* Cancel the request when invoke this method.
|
|
626
|
+
*/
|
|
627
|
+
cancel(cb?: (reason: any) => void): StatefulPromise<FetchBlobResponse>;
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Add an event listener which triggers when data receiving from server.
|
|
631
|
+
*/
|
|
632
|
+
progress(callback: (received: string, total: string) => void): StatefulPromise<FetchBlobResponse>;
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Add an event listener with custom configuration
|
|
636
|
+
*/
|
|
637
|
+
progress(config: { count?: number; interval?: number }, callback: (received: number, total: number) => void): StatefulPromise<FetchBlobResponse>;
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Add an event listener with custom configuration.
|
|
641
|
+
*/
|
|
642
|
+
uploadProgress(callback: (sent: number, total: number) => void): StatefulPromise<FetchBlobResponse>;
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Add an event listener with custom configuration
|
|
646
|
+
*/
|
|
647
|
+
uploadProgress(config: { count?: number; interval?: number }, callback: (sent: number, total: number) => void): StatefulPromise<FetchBlobResponse>;
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* An IOS only API, when IOS app turns into background network tasks will be terminated after ~180 seconds,
|
|
651
|
+
* in order to handle these expired tasks, you can register an event handler, which will be called after the
|
|
652
|
+
* app become active.
|
|
653
|
+
*/
|
|
654
|
+
expire(callback: () => void): StatefulPromise<void>;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
export declare class ReactNativeBlobUtilSession {
|
|
658
|
+
constructor(name: string, list: string[]);
|
|
659
|
+
|
|
660
|
+
add(path: string): ReactNativeBlobUtilSession;
|
|
661
|
+
|
|
662
|
+
remove(path: string): ReactNativeBlobUtilSession;
|
|
663
|
+
|
|
664
|
+
dispose(): Promise<void>;
|
|
665
|
+
|
|
666
|
+
list(): string[];
|
|
667
|
+
|
|
668
|
+
name: string;
|
|
669
|
+
|
|
670
|
+
static getSession(name: string): any;
|
|
671
|
+
|
|
672
|
+
static setSession(name: string): void;
|
|
673
|
+
|
|
674
|
+
static removeSession(name: string): void;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* A set of configurations that will be injected into a fetch method, with the following properties.
|
|
679
|
+
*/
|
|
680
|
+
export interface ReactNativeBlobUtilConfig {
|
|
681
|
+
Progress?: { count?: number; interval?: number };
|
|
682
|
+
UploadProgress?: { count?: number; interval?: number };
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* When this property is true, the downloaded data will overwrite the existing file. (true by default)
|
|
686
|
+
*/
|
|
687
|
+
overwrite?: boolean;
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* Set timeout of the request (in milliseconds).
|
|
691
|
+
*/
|
|
692
|
+
timeout?: number;
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* Set this property to true to display a network indicator on status bar, this feature is only supported on IOS.
|
|
696
|
+
*/
|
|
697
|
+
indicator?: boolean;
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Set this property to true will allow the request create connection with server have self-signed SSL
|
|
701
|
+
* certification. This is not recommended to use in production.
|
|
702
|
+
*/
|
|
703
|
+
trusty?: boolean;
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Set this property to true will only do requests through the WiFi interface, and fail otherwise.
|
|
707
|
+
*/
|
|
708
|
+
wifiOnly?: boolean;
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* Set this property so redirects are not automatically followed.
|
|
712
|
+
*/
|
|
713
|
+
followRedirect?: boolean;
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Set this property to true will makes response data of the fetch stored in a temp file, by default the temp
|
|
717
|
+
* file will stored in App's own root folder with file name template ReactNativeBlobUtil_tmp${timestamp}.
|
|
718
|
+
*/
|
|
719
|
+
fileCache?: boolean;
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Set this property to true if you want the data to be processed before it gets written onto disk.
|
|
723
|
+
* This only has effect if the FileTransformer has been registered and the library is configured to write
|
|
724
|
+
* response onto disk.
|
|
725
|
+
*/
|
|
726
|
+
transformFile?: boolean;
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* Set this property to change temp file extension that created by fetch response data.
|
|
730
|
+
*/
|
|
731
|
+
appendExt?: string;
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* When this property has value, fetch API will try to store response data in the path ignoring fileCache and
|
|
735
|
+
* appendExt property.
|
|
736
|
+
*/
|
|
737
|
+
path?: string;
|
|
738
|
+
|
|
739
|
+
session?: string;
|
|
740
|
+
|
|
741
|
+
addAndroidDownloads?: AddAndroidDownloads;
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* Fix IOS request timeout issue #368 by change default request setting to defaultSessionConfiguration, and make backgroundSessionConfigurationWithIdentifier optional
|
|
745
|
+
*/
|
|
746
|
+
IOSBackgroundTask?: boolean;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
export interface AddAndroidDownloads {
|
|
750
|
+
/**
|
|
751
|
+
* download file using Android download manager or not.
|
|
752
|
+
*/
|
|
753
|
+
useDownloadManager?: boolean;
|
|
754
|
+
/**
|
|
755
|
+
* title of the file
|
|
756
|
+
*/
|
|
757
|
+
title?: string;
|
|
758
|
+
/**
|
|
759
|
+
* File description of the file.
|
|
760
|
+
*/
|
|
761
|
+
description?: string;
|
|
762
|
+
/**
|
|
763
|
+
* The destination which the file will be downloaded, it SHOULD be a location on external storage (DCIMDir).
|
|
764
|
+
*/
|
|
765
|
+
path?: string;
|
|
766
|
+
/**
|
|
767
|
+
* MIME type of the file. By default is text/plain
|
|
768
|
+
*/
|
|
769
|
+
mime?: string;
|
|
770
|
+
/**
|
|
771
|
+
* A boolean value, see Officail Document
|
|
772
|
+
* (https://developer.android.com/reference/android/app/DownloadManager.html#addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean))
|
|
773
|
+
*/
|
|
774
|
+
mediaScannable?: boolean;
|
|
775
|
+
/**
|
|
776
|
+
* Only for Android >= Q; Enforces the file being stored to the MediaCollection Downloads. This might overwrite any value given in "path"
|
|
777
|
+
*/
|
|
778
|
+
storeInDownloads?: boolean;
|
|
779
|
+
/**
|
|
780
|
+
* A boolean value decide whether show a notification when download complete.
|
|
781
|
+
*/
|
|
782
|
+
notification?: boolean;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
export interface ReactNativeBlobUtilResponseInfo {
|
|
786
|
+
taskId: string;
|
|
787
|
+
state: string;
|
|
788
|
+
headers: any;
|
|
789
|
+
redirects: string[];
|
|
790
|
+
status: number;
|
|
791
|
+
respType: "text" | "blob" | "" | "json";
|
|
792
|
+
rnfbEncode: "path" | "base64" | "ascii" | "utf8";
|
|
793
|
+
timeout: boolean;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
export interface ReactNativeBlobUtilStream {
|
|
797
|
+
onData(): void;
|
|
798
|
+
|
|
799
|
+
onError(): void;
|
|
800
|
+
|
|
801
|
+
onEnd(): void;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
export declare class ReactNativeBlobUtilFile {}
|
|
805
|
+
|
|
806
|
+
export declare class ReactNativeBlobUtilStat {
|
|
807
|
+
lastModified: number;
|
|
808
|
+
size: number;
|
|
809
|
+
type: "directory" | "file";
|
|
810
|
+
path: string;
|
|
811
|
+
filename: string;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
export type Mediatype = "Audio" | "Image" | "Video" | "Download";
|
|
815
|
+
|
|
816
|
+
export interface MediaCollection {
|
|
817
|
+
/**
|
|
818
|
+
* Creates a new File in the collection.
|
|
819
|
+
* Promise will resolve to content UIR or error message
|
|
820
|
+
* @param filedata descriptor for the media store entry
|
|
821
|
+
* @param mediatype
|
|
822
|
+
* @param path path of the file being copied
|
|
823
|
+
*/
|
|
824
|
+
copyToMediaStore(filedata: filedescriptor, mediatype: Mediatype, path: string): Promise<string>;
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Creates a new File in the collection.
|
|
828
|
+
* @param filedata
|
|
829
|
+
* @param mediatype
|
|
830
|
+
*/
|
|
831
|
+
createMediafile(filedata: filedescriptor, mediatype: Mediatype): Promise<string>;
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Copies an existing file to a mediastore file
|
|
835
|
+
* @param uri URI of the destination mediastore file
|
|
836
|
+
* @param path Path to the existing file which should be copied
|
|
837
|
+
*/
|
|
838
|
+
writeToMediafile(uri: string, path: string): Promise<string>;
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Copies and transforms an existing file to a mediastore file. Make sure FileTransformer is set
|
|
842
|
+
* @param uri URI of the destination mediastore file
|
|
843
|
+
* @param path Path to the existing file which should be copied
|
|
844
|
+
*/
|
|
845
|
+
writeToMediafileWithTransform(uri: string, path: string): Promise<string>;
|
|
846
|
+
|
|
847
|
+
/**
|
|
848
|
+
* Copies a file from the mediastore to the apps internal storage
|
|
849
|
+
* @param contenturi URI of the mediastore file
|
|
850
|
+
* @param destpath Path for the file in the internal storage
|
|
851
|
+
*/
|
|
852
|
+
copyToInternal(contenturi: string, destpath: string): Promise<string>;
|
|
853
|
+
|
|
854
|
+
/**
|
|
855
|
+
* Gets the blob data for a given URI in the mediastore
|
|
856
|
+
* @param contenturi
|
|
857
|
+
* @param encoding
|
|
858
|
+
*/
|
|
859
|
+
getBlob(contenturi: string, encoding: string): Promise<string>;
|
|
860
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { NativeModules, Platform } from 'react-native';
|
|
2
|
-
import
|
|
2
|
+
import {DownloadManager} from './download';
|
|
3
3
|
const LINKING_ERROR =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
'The package \'rn-hotupdate\' doesn\'t seem to be linked. Make sure: \n\n' +
|
|
5
|
+
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
|
|
6
|
+
'- You rebuilt the app after installing the package\n' +
|
|
7
|
+
'- You are not using Expo Go\n';
|
|
8
8
|
|
|
9
9
|
export interface UpdateOption {
|
|
10
10
|
headers?: object
|
|
@@ -12,19 +12,20 @@ export interface UpdateOption {
|
|
|
12
12
|
updateSuccess?(): void
|
|
13
13
|
updateFail?(message?: string): void
|
|
14
14
|
restartAfterInstall?: boolean
|
|
15
|
+
extensionBundle?: string,
|
|
15
16
|
}
|
|
16
17
|
const RNhotupdate = NativeModules.RNhotupdate
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
? NativeModules.RNhotupdate
|
|
19
|
+
: new Proxy(
|
|
20
|
+
{},
|
|
21
|
+
{
|
|
22
|
+
get() {
|
|
23
|
+
throw new Error(LINKING_ERROR);
|
|
24
|
+
},
|
|
25
|
+
}
|
|
25
26
|
);
|
|
26
|
-
const downloadBundleFile = async (uri: string, headers?: object, callback?: (received: string, total: string) => void) => {
|
|
27
|
-
const res = await
|
|
27
|
+
const downloadBundleFile = async (downloadManager: DownloadManager, uri: string, headers?: object, callback?: (received: string, total: string) => void) => {
|
|
28
|
+
const res = await downloadManager
|
|
28
29
|
.config({
|
|
29
30
|
fileCache: Platform.OS === 'android',
|
|
30
31
|
})
|
|
@@ -38,8 +39,8 @@ const downloadBundleFile = async (uri: string, headers?: object, callback?: (rec
|
|
|
38
39
|
});
|
|
39
40
|
return res.path();
|
|
40
41
|
};
|
|
41
|
-
function setupBundlePath(path: string): Promise<boolean> {
|
|
42
|
-
return RNhotupdate.setupBundlePath(path);
|
|
42
|
+
function setupBundlePath(path: string, extension?: string): Promise<boolean> {
|
|
43
|
+
return RNhotupdate.setupBundlePath(path, extension);
|
|
43
44
|
}
|
|
44
45
|
function deleteBundlePath(): Promise<boolean> {
|
|
45
46
|
return RNhotupdate.deleteBundle();
|
|
@@ -73,7 +74,7 @@ const installFail = (option?: UpdateOption, e?: any) => {
|
|
|
73
74
|
option?.updateFail?.(JSON.stringify(e));
|
|
74
75
|
console.error('Download bundle fail', JSON.stringify(e));
|
|
75
76
|
};
|
|
76
|
-
async function downloadBundleUri(uri: string, version: number, option?: UpdateOption) {
|
|
77
|
+
async function downloadBundleUri(downloadManager: DownloadManager, uri: string, version: number, option?: UpdateOption) {
|
|
77
78
|
if (!uri) {
|
|
78
79
|
installFail(option, 'Please give a valid URL!');
|
|
79
80
|
return;
|
|
@@ -88,9 +89,9 @@ async function downloadBundleUri(uri: string, version: number, option?: UpdateOp
|
|
|
88
89
|
return;
|
|
89
90
|
}
|
|
90
91
|
try {
|
|
91
|
-
const path = await downloadBundleFile(uri, option?.headers, option?.progress);
|
|
92
|
+
const path = await downloadBundleFile(downloadManager, uri, option?.headers, option?.progress);
|
|
92
93
|
if (path) {
|
|
93
|
-
setupBundlePath(path).then(success => {
|
|
94
|
+
setupBundlePath(path, option?.extensionBundle).then(success => {
|
|
94
95
|
if (success) {
|
|
95
96
|
setCurrentVersion(version);
|
|
96
97
|
option?.updateSuccess?.();
|