rn-file-toolkit 1.0.1 → 1.0.2
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 +83 -433
- package/android/src/main/java/com/filetoolkit/FileToolkitModule.kt +123 -2
- package/ios/FileToolkit.mm +61 -19
- package/lib/commonjs/index.js +147 -562
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +147 -562
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +27 -443
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +27 -443
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.tsx +177 -783
package/README.md
CHANGED
|
@@ -6,516 +6,166 @@
|
|
|
6
6
|
[](https://www.typescriptlang.org/)
|
|
7
7
|
[](https://github.com/chavan-labs/rn-file-toolkit)
|
|
8
8
|
|
|
9
|
-
The
|
|
10
|
-
|
|
11
|
-
> 100% pure native code (Kotlin + Swift). Zero third-party dependencies.
|
|
12
|
-
|
|
13
|
-
**Keywords:** react native download, react native file download, react native background download, react native download manager, react native file upload, react native download progress, react native pause resume download, react native cache manager, react native turbo module, expo download, iOS URLSession, Android DownloadManager, react native checksum validation, base64 converter, url to base64, data uri, share file, open file, file sharing, native share, document viewer, download queue, concurrent downloads, queue concurrency, priority queue, batch download, max concurrent downloads, react native filesystem, read file, write file, copy file, move file, stat file, file exists, useDownload hook, download speed, download eta, download progress bytes
|
|
14
|
-
|
|
15
|
-
⭐ **Star this repo if you found it useful** — it helps others discover the project!
|
|
16
|
-
|
|
17
|
-
## Problems?
|
|
18
|
-
|
|
19
|
-
Most React Native file download solutions have one or more of these problems:
|
|
20
|
-
|
|
21
|
-
- **Complexity** — require configuring native modules, background tasks, and notification channels separately
|
|
22
|
-
- **Dependencies** — rely on heavy third-party libraries that bloat your app size
|
|
23
|
-
- **Limited features** — lack pause/resume, checksum validation, or proper background support
|
|
24
|
-
- **No queue** — spawn 20 downloads and you'll crash or saturate the network; libraries like `react-native-blob-util` have no queue at all
|
|
25
|
-
- **Split libraries** — downloading is in one package, filesystem operations in another (read/write/copy/stat/exists), adding extra dependency and complexity
|
|
26
|
-
- **Poor DX** — complicated APIs that require managing multiple IDs, listeners, and cleanup logic
|
|
27
|
-
|
|
28
|
-
**rn-file-toolkit** was built to solve these issues. It provides a simple, unified API while leveraging platform-native download managers (URLSession on iOS, DownloadManager on Android) for reliable, battery-efficient downloads. Everything works out of the box — background downloads, progress tracking, pause/resume — without wrestling with native configuration.
|
|
29
|
-
|
|
30
|
-
## ✨ Features
|
|
31
|
-
|
|
32
|
-
- **`useDownload()` hook** — drop-in React hook with built-in state: `status`, `progress`, `result`, `pause`, `resume`, `cancel` — no competitors have this
|
|
33
|
-
- **Rich progress info** — `onProgress` gives you `percent`, `bytesDownloaded`, `totalBytes`, `speedBps`, and `etaSeconds` — not just a plain number
|
|
34
|
-
- **Zip & Unzip** — compress files/directories and extract ZIP archives natively with **zero third-party dependencies** (`java.util.zip` on Android, system `zlib` on iOS)
|
|
35
|
-
- **Download with progress** — clean `0 → 100` progress natively, no UI freezing
|
|
36
|
-
- **Background downloads** — survive app suspension (iOS background URLSession + Android DownloadManager)
|
|
37
|
-
- **Download Queue** — built-in concurrency-limited queue with `maxConcurrent` control and `high`/`normal` priority
|
|
38
|
-
- **Pause & Resume** — resume mid-download using HTTP Range requests
|
|
39
|
-
- **Auto-Retry** — automatic retry on network errors with exponential backoff
|
|
40
|
-
- **Cancel** — cancel any active download, partial files are cleaned up automatically
|
|
41
|
-
- **Re-attach** — reconnect to background downloads after app restart
|
|
42
|
-
- **Custom Headers** — support for Authorization tokens and custom metadata
|
|
43
|
-
- **Custom Destinations** — save to `downloads`, `cache`, or `documents` folders
|
|
44
|
-
- **Multipart Upload** — simple, native file uploading
|
|
45
|
-
- **Checksum Validation** — verify file integrity (MD5, SHA1, SHA256) after download
|
|
46
|
-
- **Base64 & Data URI Support** — convert base64 strings and data URIs to files natively
|
|
47
|
-
- **URL to Base64** — convert remote URLs (images, videos, gifs) to base64 strings
|
|
48
|
-
- **Share Files** — share files with other apps using native share dialog
|
|
49
|
-
- **Open Files** — open files with default apps or app chooser
|
|
50
|
-
- **Filesystem API (`fs`)** — `exists`, `stat`, `readFile`, `writeFile`, `copyFile`, `moveFile`, `mkdir`, `ls`, `deleteFile`
|
|
51
|
-
- **Expo Support** — includes a config plugin for zero-config integration
|
|
52
|
-
- **TurboModules** — built on the React Native New Architecture
|
|
53
|
-
- **File management** — list, delete individual files, or clear all downloads
|
|
9
|
+
The ultimate, unified file management library for React Native. Download, upload, manage queues, and interact with the filesystem—all powered by pure native implementations (Kotlin + Swift) with **zero third-party dependencies**.
|
|
54
10
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
## Installation
|
|
58
|
-
|
|
59
|
-
```sh
|
|
60
|
-
npm install rn-file-toolkit
|
|
61
|
-
```
|
|
11
|
+
⭐ **Star this repo if you found it useful!**
|
|
62
12
|
|
|
63
13
|
---
|
|
64
14
|
|
|
65
|
-
##
|
|
66
|
-
|
|
67
|
-
### `download(options)`
|
|
68
|
-
|
|
69
|
-
```javascript
|
|
70
|
-
import { download } from 'rn-file-toolkit';
|
|
15
|
+
## Why rn-file-toolkit?
|
|
16
|
+
Most React Native file solutions are fragmented, bloated, or lack critical features like background queues or stable pause/resume. **rn-file-toolkit** gives you a unified, TurboModule-powered API utilizing OS-native download managers (`URLSession` on iOS, `DownloadManager` on Android) for reliable, battery-efficient file operations.
|
|
71
17
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
},
|
|
81
|
-
onProgress: ({
|
|
82
|
-
percent,
|
|
83
|
-
bytesDownloaded,
|
|
84
|
-
totalBytes,
|
|
85
|
-
speedBps,
|
|
86
|
-
etaSeconds,
|
|
87
|
-
}) => {
|
|
88
|
-
console.log(
|
|
89
|
-
`${percent.toFixed(1)}% — ${(speedBps / 1024).toFixed(
|
|
90
|
-
1
|
|
91
|
-
)} KB/s — ETA ${etaSeconds.toFixed(0)}s`
|
|
92
|
-
);
|
|
93
|
-
},
|
|
94
|
-
// Auto-retry on network failure (optional)
|
|
95
|
-
retry: {
|
|
96
|
-
attempts: 3, // max retry attempts
|
|
97
|
-
delay: 1000, // base delay in ms; doubles each attempt: 1s → 2s → 4s (capped at 30s)
|
|
98
|
-
onRetry: (attempt, error) => console.log(`Retry #${attempt}: ${error}`),
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
> **Retry behaviour:**
|
|
104
|
-
>
|
|
105
|
-
> - Only retries on **network errors** (timeouts, connection drops, socket errors).
|
|
106
|
-
> - Server errors (`4xx`/`5xx`) and checksum mismatches are **not** retried.
|
|
107
|
-
> - Delay doubles each attempt (exponential backoff), capped at 30 seconds.
|
|
108
|
-
> - Works on both iOS and Android for foreground downloads.
|
|
18
|
+
### ✨ Key Features
|
|
19
|
+
- **Drop-in `useDownload()` Hook:** Built-in state management (`status`, `progress`, `result`) and controls (`pause`, `resume`, `cancel`).
|
|
20
|
+
- **Background Downloads:** Survives app suspension with automatic re-attachment capabilities.
|
|
21
|
+
- **Smart Queueing:** Cap concurrency and set priorities (`high`/`normal`) without native configuration.
|
|
22
|
+
- **Resilient:** Auto-retries on network errors with exponential backoff and Range-based HTTP resume.
|
|
23
|
+
- **Zero-Dependency Zip/Unzip:** Uses native `java.util.zip` and iOS `zlib` for extracting/compressing files.
|
|
24
|
+
- **Rich File System API:** `readFile`, `writeFile`, `copyFile`, `moveFile`, `mkdir`, `ls`, `stat`, `exists`, and `deleteFile`.
|
|
25
|
+
- **Media Utilities:** Base64 encoding/decoding, URL to Base64 conversions, and native share/open dialogs.
|
|
109
26
|
|
|
110
27
|
---
|
|
111
28
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
Avoid crashing your app (or saturating the network) when kicking off many simultaneous downloads. The built-in queue lets you cap concurrency and prioritise individual items — all in pure JavaScript, with zero native changes required.
|
|
115
|
-
|
|
116
|
-
```javascript
|
|
117
|
-
import { download, setQueueOptions, getQueueStatus } from 'rn-file-toolkit';
|
|
118
|
-
|
|
119
|
-
// 1. Configure the global queue (call once, e.g. at app startup)
|
|
120
|
-
setQueueOptions({ maxConcurrent: 3 }); // default is 3
|
|
121
|
-
|
|
122
|
-
// 2. Enqueue downloads — at most 3 will run at the same time
|
|
123
|
-
const promises = urls.map((url) =>
|
|
124
|
-
download({
|
|
125
|
-
url,
|
|
126
|
-
destination: 'documents',
|
|
127
|
-
queue: true, // join the managed queue
|
|
128
|
-
priority: 'normal', // 'high' | 'normal' (default)
|
|
129
|
-
onProgress: (p) => console.log(`${url}: ${p.percent}%`),
|
|
130
|
-
})
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
const results = await Promise.all(promises);
|
|
134
|
-
|
|
135
|
-
// High-priority item jumps ahead of all 'normal' pending items
|
|
136
|
-
download({
|
|
137
|
-
url: 'https://example.com/urgent.pdf',
|
|
138
|
-
queue: true,
|
|
139
|
-
priority: 'high',
|
|
140
|
-
});
|
|
29
|
+
## Installation
|
|
141
30
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
console.log(`Running: ${active} Waiting: ${pending} Limit: ${maxConcurrent}`);
|
|
31
|
+
```sh
|
|
32
|
+
npm install rn-file-toolkit
|
|
145
33
|
```
|
|
146
34
|
|
|
147
|
-
> **Queue behaviour:**
|
|
148
|
-
>
|
|
149
|
-
> - `queue: false` (default) — download starts immediately, bypassing the queue entirely. All existing behaviour is unchanged.
|
|
150
|
-
> - `queue: true` — the download is placed in the JS queue. It starts as soon as an active slot is free.
|
|
151
|
-
> - `priority: 'high'` — item is inserted at the **front** of the pending list, so it runs before any `'normal'` items.
|
|
152
|
-
> - `priority: 'normal'` (default) — item is appended to the **back**.
|
|
153
|
-
> - `setQueueOptions` can be called at any time; if `maxConcurrent` is increased, idle slots are filled immediately.
|
|
154
|
-
> - All other `DownloadOptions` (`onProgress`, `retry`, `checksum`, `headers`, etc.) work exactly the same inside the queue.
|
|
155
|
-
|
|
156
35
|
---
|
|
157
36
|
|
|
158
|
-
|
|
37
|
+
## Quick Start: `useDownload` Hook
|
|
159
38
|
|
|
160
|
-
The easiest way to manage a download inside a React component. Get status, rich progress (with speed & ETA), and full controls
|
|
39
|
+
The easiest way to manage a download inside a React component. Get status, rich progress (with speed & ETA), and full controls out of the box.
|
|
161
40
|
|
|
162
41
|
```tsx
|
|
163
42
|
import { useDownload } from 'rn-file-toolkit';
|
|
164
43
|
|
|
165
44
|
function DownloadScreen() {
|
|
166
|
-
const { start, pause, resume, cancel, status, progress, result } =
|
|
167
|
-
useDownload();
|
|
45
|
+
const { start, pause, resume, cancel, status, progress, result } = useDownload();
|
|
168
46
|
|
|
169
47
|
return (
|
|
170
48
|
<View>
|
|
171
|
-
<Button
|
|
172
|
-
title="Download"
|
|
173
|
-
onPress={() =>
|
|
174
|
-
start({
|
|
175
|
-
url: 'https://example.com/video.mp4',
|
|
176
|
-
destination: 'documents',
|
|
177
|
-
})
|
|
178
|
-
}
|
|
49
|
+
<Button
|
|
50
|
+
title="Download"
|
|
51
|
+
onPress={() => start({ url: 'https://example.com/video.mp4', destination: 'documents' })}
|
|
179
52
|
/>
|
|
180
53
|
|
|
181
54
|
{status === 'downloading' && progress && (
|
|
182
55
|
<View>
|
|
183
|
-
<Text>{progress.percent.toFixed(1)}
|
|
184
|
-
<Text>Speed: {(progress.speedBps / 1024).toFixed(1)} KB/s</Text>
|
|
56
|
+
<Text>{progress.percent.toFixed(1)}% ({(progress.speedBps / 1024).toFixed(1)} KB/s)</Text>
|
|
185
57
|
<Text>ETA: {progress.etaSeconds.toFixed(0)}s</Text>
|
|
186
|
-
<Text>
|
|
187
|
-
{(progress.bytesDownloaded / 1024 / 1024).toFixed(1)} MB
|
|
188
|
-
{' / '}
|
|
189
|
-
{(progress.totalBytes / 1024 / 1024).toFixed(1)} MB
|
|
190
|
-
</Text>
|
|
191
58
|
<Button title="Pause" onPress={pause} />
|
|
192
59
|
<Button title="Cancel" onPress={cancel} />
|
|
193
60
|
</View>
|
|
194
61
|
)}
|
|
195
62
|
|
|
196
63
|
{status === 'paused' && <Button title="Resume" onPress={resume} />}
|
|
197
|
-
|
|
198
|
-
{status === 'done' && result?.success && (
|
|
199
|
-
<Text>✅ Saved to: {result.filePath}</Text>
|
|
200
|
-
)}
|
|
201
|
-
|
|
64
|
+
{status === 'done' && <Text>✅ Saved to: {result?.filePath}</Text>}
|
|
202
65
|
{status === 'error' && <Text>❌ {result?.error}</Text>}
|
|
203
66
|
</View>
|
|
204
67
|
);
|
|
205
68
|
}
|
|
206
69
|
```
|
|
207
70
|
|
|
208
|
-
| Property | Type | Description |
|
|
209
|
-
| ---------------- | ---------------------------------------------------------- | ------------------------------- |
|
|
210
|
-
| `start(options)` | `(options: DownloadOptions) => Promise<DownloadResult>` | Start a download |
|
|
211
|
-
| `pause()` | `() => Promise<void>` | Pause the active download |
|
|
212
|
-
| `resume()` | `() => Promise<void>` | Resume a paused download |
|
|
213
|
-
| `cancel()` | `() => Promise<void>` | Cancel and discard the download |
|
|
214
|
-
| `status` | `'idle' \| 'downloading' \| 'paused' \| 'done' \| 'error'` | Current state |
|
|
215
|
-
| `progress` | `ProgressInfo \| null` | Live progress info (see below) |
|
|
216
|
-
| `result` | `DownloadResult \| null` | Final result once complete |
|
|
217
|
-
| `downloadId` | `string \| null` | Active download ID |
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
### `upload(options)`
|
|
222
|
-
|
|
223
|
-
```javascript
|
|
224
|
-
import { upload } from 'rn-file-toolkit';
|
|
225
|
-
|
|
226
|
-
const result = await upload({
|
|
227
|
-
url: 'https://example.com/api/upload',
|
|
228
|
-
filePath: '/path/to/my_image.jpg',
|
|
229
|
-
fieldName: 'avatar', // default: 'file'
|
|
230
|
-
parameters: {
|
|
231
|
-
userId: '123',
|
|
232
|
-
},
|
|
233
|
-
headers: { 'X-Custom-Header': 'value' },
|
|
234
|
-
onProgress: (p) => console.log(`Uploading: ${p}%`),
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
if (result.success) {
|
|
238
|
-
console.log('Response:', result.data);
|
|
239
|
-
}
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
---
|
|
243
|
-
|
|
244
|
-
### `saveBase64AsFile(options)`
|
|
245
|
-
|
|
246
|
-
Save a base64 string or data URI as a file. Perfect for handling base64 images, documents, or any binary data.
|
|
247
|
-
|
|
248
|
-
```javascript
|
|
249
|
-
import { saveBase64AsFile } from 'rn-file-toolkit';
|
|
250
|
-
|
|
251
|
-
// From data URI (auto-detects file extension)
|
|
252
|
-
const result = await saveBase64AsFile({
|
|
253
|
-
base64Data: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...',
|
|
254
|
-
fileName: 'photo.png',
|
|
255
|
-
destination: 'documents', // 'downloads' | 'cache' | 'documents'
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
// From plain base64 string
|
|
259
|
-
const result = await saveBase64AsFile({
|
|
260
|
-
base64Data: 'SGVsbG8gV29ybGQ=',
|
|
261
|
-
fileName: 'hello.txt',
|
|
262
|
-
destination: 'cache',
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
if (result.success) {
|
|
266
|
-
console.log('File saved at:', result.filePath);
|
|
267
|
-
}
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
---
|
|
271
|
-
|
|
272
|
-
### `urlToBase64(options)`
|
|
273
|
-
|
|
274
|
-
Convert a web URL (image, video, gif, etc.) to base64 string. Perfect for converting remote media to base64 for local processing.
|
|
275
|
-
|
|
276
|
-
```javascript
|
|
277
|
-
import { urlToBase64 } from 'rn-file-toolkit';
|
|
278
|
-
|
|
279
|
-
const result = await urlToBase64({
|
|
280
|
-
url: 'https://example.com/photo.jpg',
|
|
281
|
-
headers: { Authorization: 'Bearer <token>' }, // optional
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
if (result.success) {
|
|
285
|
-
console.log('Base64:', result.base64);
|
|
286
|
-
console.log('Data URI:', result.dataUri);
|
|
287
|
-
console.log('MIME Type:', result.mimeType); // e.g., 'image/jpeg'
|
|
288
|
-
|
|
289
|
-
// Use in Image component
|
|
290
|
-
// <Image source={{ uri: result.dataUri }} />
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
71
|
---
|
|
295
72
|
|
|
296
|
-
|
|
73
|
+
## Core APIs
|
|
297
74
|
|
|
298
|
-
|
|
75
|
+
### `download(options)`
|
|
76
|
+
For programmatic, queue-aware background downloads.
|
|
299
77
|
|
|
300
78
|
```javascript
|
|
301
|
-
import {
|
|
302
|
-
|
|
303
|
-
const result = await shareFile({
|
|
304
|
-
filePath: '/path/to/document.pdf',
|
|
305
|
-
title: 'Share Document', // Android only
|
|
306
|
-
subject: 'Check this out', // Android only
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
if (result.success) {
|
|
310
|
-
console.log('File shared successfully');
|
|
311
|
-
}
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
---
|
|
315
|
-
|
|
316
|
-
### `openFile(options)`
|
|
79
|
+
import { download, setQueueOptions } from 'rn-file-toolkit';
|
|
317
80
|
|
|
318
|
-
|
|
81
|
+
// Optional: Configure global concurrency queue
|
|
82
|
+
setQueueOptions({ maxConcurrent: 3 });
|
|
319
83
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
84
|
+
const result = await download({
|
|
85
|
+
url: 'https://example.com/file.pdf',
|
|
86
|
+
destination: 'documents', // 'downloads' | 'cache' | 'documents'
|
|
87
|
+
queue: true, // Joins the managed queue
|
|
88
|
+
priority: 'high', // 'high' | 'normal'
|
|
89
|
+
retry: { attempts: 3, delay: 1000 },
|
|
90
|
+
checksum: { hash: 'd41d8cd...', algorithm: 'md5' },
|
|
91
|
+
onProgress: (p) => console.log(`${p.percent.toFixed(1)}%`),
|
|
326
92
|
});
|
|
327
|
-
|
|
328
|
-
if (result.success) {
|
|
329
|
-
console.log('File opened');
|
|
330
|
-
}
|
|
331
93
|
```
|
|
332
94
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
### `unzip(sourcePath, destDir)` · `zip(sourcePath, destPath)`
|
|
336
|
-
|
|
337
|
-
Compress and extract ZIP archives natively — **no third-party library required**.
|
|
338
|
-
|
|
339
|
-
- **Android** uses `java.util.zip` (built into the Android SDK, every API level).
|
|
340
|
-
- **iOS** uses `zlib` (system framework, linked via `s.libraries = 'z'` in the podspec — ships on every iPhone/iPad).
|
|
95
|
+
### `upload(options)`
|
|
96
|
+
Robust, memory-efficient multipart file uploading.
|
|
341
97
|
|
|
342
98
|
```javascript
|
|
343
|
-
import {
|
|
99
|
+
import { upload } from 'rn-file-toolkit';
|
|
344
100
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
101
|
+
const result = await upload({
|
|
102
|
+
url: 'https://example.com/api/upload',
|
|
103
|
+
filePath: '/path/to/my_image.jpg',
|
|
104
|
+
fieldName: 'avatar',
|
|
105
|
+
parameters: { userId: '123' },
|
|
106
|
+
onProgress: (p) => console.log(`Uploading: ${p}%`),
|
|
349
107
|
});
|
|
350
|
-
|
|
351
|
-
if (dl.success) {
|
|
352
|
-
const result = await unzip(
|
|
353
|
-
dl.filePath, // absolute path to the .zip file
|
|
354
|
-
'/path/to/output-folder' // destination directory (created if it doesn't exist)
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
if (result.success) {
|
|
358
|
-
console.log('Destination:', result.destDir);
|
|
359
|
-
console.log('Extracted files:', result.files);
|
|
360
|
-
// result.files → ['/path/to/output-folder/image.png', ...]
|
|
361
|
-
} else {
|
|
362
|
-
console.log('Error:', result.error);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
// ── Zip a single file ───────────────────────────────────────────────────────
|
|
367
|
-
const zipResult = await zip(
|
|
368
|
-
'/path/to/document.pdf', // source file
|
|
369
|
-
'/path/to/document.zip' // output archive path
|
|
370
|
-
);
|
|
371
|
-
|
|
372
|
-
if (zipResult.success) {
|
|
373
|
-
console.log('Archive created at:', zipResult.zipPath);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
// ── Zip an entire directory ─────────────────────────────────────────────────
|
|
377
|
-
const dirResult = await zip(
|
|
378
|
-
'/path/to/my-folder', // source directory
|
|
379
|
-
'/path/to/my-folder.zip' // output archive path
|
|
380
|
-
);
|
|
381
108
|
```
|
|
382
109
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
> - `unzip` auto-creates the destination directory including any intermediate folders.
|
|
386
|
-
> - `unzip` on Android protects against [zip-slip attacks](https://snyk.io/research/zip-slip-vulnerability) by validating each entry path.
|
|
387
|
-
> - `zip` supports both single files and entire directory trees (recursive).
|
|
388
|
-
> - Both functions run on a background thread and never block the JS thread.
|
|
389
|
-
> - Supported compression methods: **Deflate** (method 8) and **Store** (method 0) — the two methods used by virtually every ZIP file.
|
|
390
|
-
|
|
391
|
-
---
|
|
392
|
-
|
|
393
|
-
### Pause / Resume / Cancel
|
|
110
|
+
### Filesystem (`fs`)
|
|
111
|
+
Perform native filesystem operations directly.
|
|
394
112
|
|
|
395
113
|
```javascript
|
|
396
|
-
import {
|
|
114
|
+
import { fs } from 'rn-file-toolkit';
|
|
397
115
|
|
|
398
|
-
await
|
|
399
|
-
await
|
|
400
|
-
await
|
|
116
|
+
await fs.exists('/path/to/file.txt');
|
|
117
|
+
await fs.stat('/path/to/file.txt'); // { size, modified, isDir ... }
|
|
118
|
+
await fs.writeFile('/path/to/file.txt', 'hello', 'utf8'); // Supports 'base64'
|
|
119
|
+
await fs.copyFile('/src/file.txt', '/dst/file.txt');
|
|
120
|
+
await fs.mkdir('/path/to/folder');
|
|
121
|
+
const files = await fs.ls('/path/to/folder');
|
|
401
122
|
```
|
|
402
123
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
### Cache Management
|
|
124
|
+
### Zip & Unzip
|
|
125
|
+
Compress and extract archives securely.
|
|
406
126
|
|
|
407
127
|
```javascript
|
|
408
|
-
import {
|
|
409
|
-
|
|
410
|
-
// List all files in the cache/documents folders
|
|
411
|
-
const { files } = await getCachedFiles();
|
|
128
|
+
import { unzip, zip } from 'rn-file-toolkit';
|
|
412
129
|
|
|
413
|
-
|
|
414
|
-
await
|
|
415
|
-
|
|
416
|
-
// Clear all managed files
|
|
417
|
-
await clearCache();
|
|
130
|
+
await unzip('/path/to/assets.zip', '/path/to/output-folder');
|
|
131
|
+
await zip('/path/to/document.pdf', '/path/to/document.zip');
|
|
418
132
|
```
|
|
419
133
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
### `fs` (filesystem namespace)
|
|
423
|
-
|
|
424
|
-
Use built-in file system helpers without adding another dependency.
|
|
134
|
+
### Media & Utilities
|
|
425
135
|
|
|
426
136
|
```javascript
|
|
427
|
-
import {
|
|
428
|
-
|
|
429
|
-
await fs.exists('/path/to/file.pdf'); // → true/false
|
|
430
|
-
|
|
431
|
-
await fs.stat('/path/to/file.pdf');
|
|
432
|
-
// → { path, name, size, modified, isDir }
|
|
137
|
+
import { saveBase64AsFile, urlToBase64, shareFile, openFile } from 'rn-file-toolkit';
|
|
433
138
|
|
|
434
|
-
|
|
435
|
-
await
|
|
139
|
+
// Convert base64 / Data URIs to files
|
|
140
|
+
await saveBase64AsFile({ base64Data: 'data:image/png;base64,...', destination: 'documents' });
|
|
436
141
|
|
|
437
|
-
|
|
438
|
-
await
|
|
142
|
+
// Fetch remote media as base64
|
|
143
|
+
await urlToBase64({ url: 'https://example.com/photo.jpg' });
|
|
439
144
|
|
|
440
|
-
|
|
441
|
-
await
|
|
442
|
-
await fs.deleteFile('/path/to/file.pdf');
|
|
145
|
+
// Share with native dialog
|
|
146
|
+
await shareFile({ filePath: '/path/to/document.pdf' });
|
|
443
147
|
|
|
444
|
-
|
|
445
|
-
await
|
|
148
|
+
// Open with default app
|
|
149
|
+
await openFile({ filePath: '/path/to/document.pdf', mimeType: 'application/pdf' });
|
|
446
150
|
```
|
|
447
151
|
|
|
448
|
-
> `readFile` / `writeFile` support encodings: `'utf8'` (default) and `'base64'`.
|
|
449
|
-
|
|
450
152
|
---
|
|
451
153
|
|
|
452
|
-
##
|
|
453
|
-
|
|
454
|
-
### Download from URLs
|
|
455
|
-
|
|
456
|
-
Perfect for downloading files from remote servers with progress tracking, background support, and resume capability.
|
|
154
|
+
## API Type Reference
|
|
457
155
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
Convert remote media (images, videos, gifs) to base64 strings for:
|
|
461
|
-
|
|
462
|
-
- Display in Image components without downloading to disk
|
|
463
|
-
- Inline embedding in HTML/emails
|
|
464
|
-
- Upload to APIs requiring base64 format
|
|
465
|
-
- Cross-platform data transfer
|
|
466
|
-
|
|
467
|
-
### Save Base64/Data URIs
|
|
468
|
-
|
|
469
|
-
Convert base64-encoded data (like images from canvas, camera, or API responses) directly to files:
|
|
470
|
-
|
|
471
|
-
- Canvas-generated images (`canvas.toDataURL()`)
|
|
472
|
-
- Camera/photo library base64 outputs
|
|
473
|
-
- API responses with base64-encoded files
|
|
474
|
-
- Email attachments in base64 format
|
|
475
|
-
|
|
476
|
-
---
|
|
477
|
-
|
|
478
|
-
## Type Reference
|
|
479
|
-
|
|
480
|
-
| Type | Fields |
|
|
481
|
-
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
156
|
+
| Type | Fields |
|
|
157
|
+
| -------------------- | ------ |
|
|
482
158
|
| `DownloadOptions` | `url`, `fileName?`, `background?`, `headers?`, `destination?`, `notificationTitle?`, `notificationDescription?`, `checksum?`, `onProgress?`, `retry?`, `queue?`, `priority?` |
|
|
483
|
-
| `ProgressInfo` | `percent`, `bytesDownloaded`, `totalBytes`, `speedBps`, `etaSeconds`
|
|
484
|
-
| `RetryOptions` | `attempts`, `delay?`, `onRetry?`
|
|
485
|
-
| `QueueOptions` | `maxConcurrent?`
|
|
486
|
-
| `
|
|
487
|
-
| `
|
|
488
|
-
| `
|
|
489
|
-
| `
|
|
490
|
-
| `FsStat` | `path`, `name`, `size`, `modified`, `isDir`
|
|
491
|
-
| `
|
|
492
|
-
| `
|
|
493
|
-
| `SaveBase64Options` | `base64Data`, `fileName?`, `destination?` |
|
|
494
|
-
| `UrlToBase64Options` | `url`, `headers?` |
|
|
495
|
-
| `ShareFileOptions` | `filePath`, `title?`, `subject?` |
|
|
496
|
-
| `OpenFileOptions` | `filePath`, `mimeType?` |
|
|
497
|
-
| `DownloadResult` | `success`, `filePath?`, `downloadId?`, `error?` |
|
|
498
|
-
| `UploadResult` | `success`, `status?`, `data?`, `error?` |
|
|
499
|
-
| `UnzipResult` | `success`, `destDir?`, `files?`, `error?` |
|
|
500
|
-
| `ZipResult` | `success`, `zipPath?`, `error?` |
|
|
501
|
-
| `SaveBase64Result` | `success`, `filePath?`, `error?` |
|
|
502
|
-
| `UrlToBase64Result` | `success`, `base64?`, `mimeType?`, `dataUri?`, `error?` |
|
|
503
|
-
| `ShareFileResult` | `success`, `completed?`, `error?` |
|
|
504
|
-
| `OpenFileResult` | `success`, `error?` |
|
|
505
|
-
| `Checksum` | `hash`, `algorithm: 'md5' \| 'sha1' \| 'sha256'` |
|
|
506
|
-
|
|
507
|
-
---
|
|
508
|
-
|
|
509
|
-
## Articles & Resources
|
|
510
|
-
|
|
511
|
-
- [**I Got Tired of React Native File Downloads Being a Mess — So I Built rn-file-toolkit**](https://medium.com/@chavanrohit413/i-got-tired-of-react-native-file-downloads-being-a-mess-so-i-built-rn-file-toolkit-29b7a8b5c743) — Deep dive into the problems with existing solutions and how rn-file-toolkit solves them
|
|
512
|
-
|
|
513
|
-
---
|
|
514
|
-
|
|
515
|
-
## Links
|
|
516
|
-
|
|
517
|
-
- [GitHub](https://github.com/chavan-labs/rn-file-toolkit)
|
|
518
|
-
- [npm](https://www.npmjs.com/package/rn-file-toolkit)
|
|
159
|
+
| `ProgressInfo` | `percent`, `bytesDownloaded`, `totalBytes`, `speedBps`, `etaSeconds` |
|
|
160
|
+
| `RetryOptions` | `attempts`, `delay?`, `onRetry?` |
|
|
161
|
+
| `QueueOptions` | `maxConcurrent?` |
|
|
162
|
+
| `DownloadResult` | `success`, `filePath?`, `downloadId?`, `error?` |
|
|
163
|
+
| `UploadOptions` | `url`, `filePath`, `fieldName?`, `headers?`, `parameters?`, `onProgress?`, `uploadId?` |
|
|
164
|
+
| `UploadResult` | `success`, `status?`, `data?`, `error?`, `uploadId?` |
|
|
165
|
+
| `UseDownloadReturn` | `start`, `pause`, `resume`, `cancel`, `status`, `progress`, `result`, `downloadId` |
|
|
166
|
+
| `FsStat` | `path`, `name`, `size`, `modified`, `isDir` |
|
|
167
|
+
| `UnzipResult` | `success`, `destDir?`, `files?`, `error?` |
|
|
168
|
+
| `ZipResult` | `success`, `zipPath?`, `error?` |
|
|
519
169
|
|
|
520
170
|
---
|
|
521
171
|
|