forked from birdofpreyru/react-native-fs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNativeReactNativeFs.ts
340 lines (286 loc) · 12.9 KB
/
NativeReactNativeFs.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
// Note: It would be better to have all these type definitions in a dedicated
// module, however as of its current version RN's Codegen does not seem to handle
// type imports correctly.
export type DownloadBeginCallbackResultT = {
jobId: number; // The download job ID, required if one wishes to cancel the download. See `stopDownload`.
statusCode: number; // The HTTP status code
contentLength: number; // The total size in bytes of the download resource
headers: StringMapT; // The HTTP response headers from the server
};
export type DownloadProgressCallbackResultT = {
jobId: number; // The download job ID, required if one wishes to cancel the download. See `stopDownload`.
contentLength: number; // The total size in bytes of the download resource
bytesWritten: number; // The number of bytes written to the file so far
};
/**
* These are options expected by native implementations of downloadFile()
* function.
*/
export type NativeDownloadFileOptionsT = {
jobId: number;
fromUrl: string; // URL to download file from
toFile: string; // Local filesystem path to save the file to
background: boolean; // Continue the download in the background after the app terminates (iOS only)
backgroundTimeout: number; // Maximum time (in milliseconds) to download an entire resource (iOS only, useful for timing out background downloads)
cacheable: boolean; // Whether the download can be stored in the shared NSURLCache (iOS only)
connectionTimeout: number; // only supported on Android yet
discretionary: boolean; // Allow the OS to control the timing and speed of the download to improve perceived performance (iOS only)
headers: StringMapT; // An object of headers to be passed to the server
progressDivider: number;
progressInterval: number;
readTimeout: number; // supported on Android and iOS
hasBeginCallback: boolean;
hasProgressCallback: boolean;
hasResumableCallback: boolean;
};
export type PickFileOptionsT = {
mimeTypes: string[];
};
export type DownloadFileOptionsT = {
fromUrl: string; // URL to download file from
toFile: string; // Local filesystem path to save the file to
background?: boolean; // Continue the download in the background after the app terminates (iOS only)
backgroundTimeout?: number; // Maximum time (in milliseconds) to download an entire resource (iOS only, useful for timing out background downloads)
cacheable?: boolean; // Whether the download can be stored in the shared NSURLCache (iOS only)
connectionTimeout?: number; // only supported on Android yet
discretionary?: boolean; // Allow the OS to control the timing and speed of the download to improve perceived performance (iOS only)
headers?: StringMapT; // An object of headers to be passed to the server
progressDivider?: number;
progressInterval?: number;
readTimeout?: number; // supported on Android and iOS
begin?: (res: DownloadBeginCallbackResultT) => void;
progress?: (res: DownloadProgressCallbackResultT) => void;
// TODO: Yeah, original typing did not have "res" argument at all,
// but the code using this type actually passes an argument to
// resumable. Should be double-checked, if we have this argument,
// or drop it.
resumable?: (res: unknown) => void; // only supported on iOS yet
};
export type DownloadResultT = {
jobId: number; // The download job ID, required if one wishes to cancel the download. See `stopDownload`.
statusCode: number; // The HTTP status code
bytesWritten: number; // The number of bytes written to the file
};
export type FileOptionsT = {
// iOS-specific.
NSFileProtectionKey?: string;
};
export type FSInfoResultT = {
totalSpace: number; // The total amount of storage space on the device (in bytes).
totalSpaceEx: number;
freeSpace: number; // The amount of available storage space on the device (in bytes).
freeSpaceEx: number;
};
export type StringMapT = { [key: string]: string };
export type MkdirOptionsT = {
// iOS-specific.
NSURLIsExcludedFromBackupKey?: boolean;
NSFileProtectionKey?: string;
};
export type ReadDirAssetsResItemT = {
name: string;
path: string;
size: number;
// TODO: Can't these be just values rather than methods?
// Ok.. the reason these are functions is that currently the library
// receives from native side "type" field, and then in JS side it compares
// it with system-dependent constant values for directory and file...
// in other words... this is an unnecessary complication.
isDirectory: () => boolean; // Is the file a directory?
isFile: () => boolean; // Is the file just a file?
};
// TODO: When it is used as return type of Androids readDirAssets()
// it is not so good, as there are no mtime and ctime fields in that case.
// Should have a dedicated type for that.
export type ReadDirResItemT = {
// Common.
mtime: Date | null; // The last modified date of the file
name: string; // The name of the item
path: string; // The absolute path to the item
size: number; // Size in bytes.
// TODO: Can't these be just values rather than methods?
// Ok.. the reason these are functions is that currently the library
// receives from native side "type" field, and then in JS side it compares
// it with system-dependent constant values for directory and file...
// in other words... this is an unnecessary complication.
isDirectory: () => boolean; // Is the file a directory?
isFile: () => boolean; // Is the file just a file?
// iOS-specific
ctime: Date | null; // The creation date of the file (iOS only)
};
// TODO: Essentially here StatResult is similar to ReadDirItem,
// but it does not contain Date fields, thus making it possible
// to pass it from native side, unlike ReadDirItem.
export type StatResultT = {
// TODO: why is this not documented?
name?: string; // The name of the item.
path: string; // The absolute path to the item
size: number; // Size in bytes
mode: number; // UNIX file mode
ctime: Date; // Created date
mtime: Date; // Last modified date
// In case of content uri this is the pointed file path,
// otherwise is the same as path.
originalFilepath: string;
// TODO: Can't these be just values?
isFile: () => boolean; // Is the file just a file?
isDirectory: () => boolean; // Is the file a directory?
// TODO: This is temporary addition,
// to make the code compile.
type?: number;
};
export type NativeReadDirResItemT = {
ctime: number;
mtime: number;
name: string;
path: string;
size: number;
type: string;
};
type NativeStatResultT = {
ctime: number; // Created date
mtime: number; // Last modified date
size: number; // Size in bytes
type: string;
mode: number; // UNIX file mode
// In case of content uri this is the pointed file path,
// otherwise is the same as path.
// TODO: This is not implemented on iOS
originalFilepath: string;
};
export type UploadFileItemT = {
name?: string; // Name of the file, if not defined then filename is used
filename: string; // Name of file
filepath: string; // Path to file
filetype?: string; // The mimetype of the file to be uploaded, if not defined it will get mimetype from `filepath` extension
};
export type UploadBeginCallbackArgT = {
jobId: number; // The upload job ID, required if one wishes to cancel the upload. See `stopUpload`.
};
export type UploadProgressCallbackArgT = {
jobId: number; // The upload job ID, required if one wishes to cancel the upload. See `stopUpload`.
totalBytesExpectedToSend: number; // The total number of bytes that will be sent to the server
totalBytesSent: number; // The number of bytes sent to the server
};
export type UploadFileOptionsT = {
toUrl: string; // URL to upload file to
binaryStreamOnly?: boolean; // Allow for binary data stream for file to be uploaded without extra headers, Default is 'false'
files: UploadFileItemT[]; // An array of objects with the file information to be uploaded.
headers?: StringMapT; // An object of headers to be passed to the server
fields?: StringMapT; // An object of fields to be passed to the server
method?: string; // Default is 'POST', supports 'POST' and 'PUT'
// TODO: Remove these future versions.
beginCallback?: (res: UploadBeginCallbackArgT) => void; // deprecated
progressCallback?: (res: UploadProgressCallbackArgT) => void; // deprecated
begin?: (res: UploadBeginCallbackArgT) => void;
progress?: (res: UploadProgressCallbackArgT) => void;
};
export type NativeUploadFileOptionsT = {
jobId: number;
toUrl: string; // URL to upload file to
binaryStreamOnly?: boolean; // Allow for binary data stream for file to be uploaded without extra headers, Default is 'false'
files: object[]; // An array of objects with the file information to be uploaded.
headers?: StringMapT; // An object of headers to be passed to the server
fields?: StringMapT; // An object of fields to be passed to the server
method?: string; // Default is 'POST', supports 'POST' and 'PUT'
hasBeginCallback: boolean;
hasProgressCallback: boolean;
};
export type UploadResultT = {
jobId: number; // The upload job ID, required if one wishes to cancel the upload. See `stopUpload`.
statusCode: number; // The HTTP status code
headers: StringMapT; // The HTTP response headers from the server
body: string; // The HTTP response body
};
type TouchOptions = {
ctime?: number;
mtime?: number;
};
export interface Spec extends TurboModule {
readonly getConstants: () => {
// System paths.
CachesDirectoryPath: string;
DocumentDirectoryPath: string;
DownloadDirectoryPath: string;
ExternalCachesDirectoryPath: string;
ExternalDirectoryPath: string;
ExternalStorageDirectoryPath: string;
MainBundlePath?: string; // not on Android
TemporaryDirectoryPath: string;
// File system entity types.
// TODO: At least on iOS there more file types we don't capture here:
// https://developer.apple.com/documentation/foundation/nsfileattributetype?language=objc
FileTypeRegular: string;
FileTypeDirectory: string;
// TODO: It was not declared in JS layer,
// but it is exported constant on Android. Do we need it?
DocumentDirectory: number;
// iOS-specific
LibraryDirectoryPath?: string;
// Windows-specific.
PicturesDirectoryPath?: string; // also on Android!
RoamingDirectoryPath?: string;
// NON-ANDROID-STUFF, AND NOT DOCUMENTED
FileProtectionKeys?: string;
};
addListener(event: string): void;
removeListeners(count: number): void;
// Common.
appendFile(path: string, b64: string): Promise<void>;
copyFile(from: string, into: string, options: FileOptionsT): Promise<void>;
downloadFile(options: NativeDownloadFileOptionsT): Promise<DownloadResultT>;
exists(path: string): Promise<boolean>;
getFSInfo(): Promise<FSInfoResultT>;
hash(path: string, algorithm: string): Promise<string>;
mkdir(path: string, options: MkdirOptionsT): Promise<void>;
moveFile(from: string, into: string, options: FileOptionsT): Promise<void>;
pickFile(options: PickFileOptionsT): Promise<string[]>;
read(path: string, length: number, position: number): Promise<string>;
readFile(path: string): Promise<string>;
// TODO: Not sure about the type of result here.
readDir(path: string): Promise<NativeReadDirResItemT[]>;
stat(path: string): Promise<NativeStatResultT>;
stopDownload(jobId: number): void;
stopUpload(jobId: number): void;
touch(path: string, options: TouchOptions): Promise<void>;
unlink(path: string): Promise<void>;
uploadFiles(options: NativeUploadFileOptionsT): Promise<UploadResultT>;
write(path: string, b64: string, position: number): Promise<void>;
writeFile(path: string, b64: string, options: FileOptionsT): Promise<void>;
// Android-specific.
copyFileAssets(from: string, into: string): Promise<void>;
copyFileRes(from: string, into: string): Promise<void>;
existsAssets(path: string): Promise<boolean>;
existsRes(path: string): Promise<boolean>;
getAllExternalFilesDirs(): Promise<string[]>;
readFileAssets(path: string): Promise<string>;
readFileRes(path: string): Promise<string>;
readDirAssets(path: string): Promise<NativeReadDirResItemT[]>;
scanFile(path: string): Promise<string | null>;
setReadable(
filepath: string,
readable: boolean,
ownerOnly: boolean,
): Promise<boolean>;
// iOS-specific.
copyAssetsFileIOS(
imageUri: string,
destPath: string,
width: number,
height: number,
scale: number,
compression: number,
resizeMode: string,
): Promise<string>;
copyAssetsVideoIOS(imageUri: string, destPath: string): Promise<string>;
completeHandlerIOS(jobId: number): void;
isResumable(jobId: number): Promise<boolean>;
pathForBundle(bundle: string): Promise<string>;
pathForGroup(group: string): Promise<string>;
resumeDownload(jobId: number): void;
// Windows-specific.
copyFolder(from: string, into: string): Promise<void>;
}
export default TurboModuleRegistry.getEnforcing<Spec>('ReactNativeFs');