@oxyhq/services 5.10.4 → 5.10.6
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 +62 -14
- package/lib/commonjs/core/OxyServices.js +797 -5
- package/lib/commonjs/core/OxyServices.js.map +1 -1
- package/lib/commonjs/core/index.js +8 -83
- package/lib/commonjs/core/index.js.map +1 -1
- package/lib/commonjs/index.js +31 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +12 -12
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js +2 -2
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignInScreen.js +1 -1
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/commonjs/ui/stores/followStore.js +4 -4
- package/lib/commonjs/ui/stores/followStore.js.map +1 -1
- package/lib/commonjs/utils/s3FileManager.js +243 -0
- package/lib/commonjs/utils/s3FileManager.js.map +1 -0
- package/lib/commonjs/utils/s3FileManagerExample.js +407 -0
- package/lib/commonjs/utils/s3FileManagerExample.js.map +1 -0
- package/lib/commonjs/utils/s3FileManagerRN.js +274 -0
- package/lib/commonjs/utils/s3FileManagerRN.js.map +1 -0
- package/lib/module/core/OxyServices.js +796 -4
- package/lib/module/core/OxyServices.js.map +1 -1
- package/lib/module/core/index.js +9 -24
- package/lib/module/core/index.js.map +1 -1
- package/lib/module/index.js +4 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +12 -12
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +2 -2
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/SignInScreen.js +1 -1
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/module/ui/stores/followStore.js +4 -4
- package/lib/module/ui/stores/followStore.js.map +1 -1
- package/lib/module/utils/s3FileManager.js +237 -0
- package/lib/module/utils/s3FileManager.js.map +1 -0
- package/lib/module/utils/s3FileManagerExample.js +400 -0
- package/lib/module/utils/s3FileManagerExample.js.map +1 -0
- package/lib/module/utils/s3FileManagerRN.js +268 -0
- package/lib/module/utils/s3FileManagerRN.js.map +1 -0
- package/lib/typescript/core/OxyServices.d.ts +292 -3
- package/lib/typescript/core/OxyServices.d.ts.map +1 -1
- package/lib/typescript/core/index.d.ts +7 -16
- package/lib/typescript/core/index.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +4 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/utils/s3FileManager.d.ts +81 -0
- package/lib/typescript/utils/s3FileManager.d.ts.map +1 -0
- package/lib/typescript/utils/s3FileManagerExample.d.ts +87 -0
- package/lib/typescript/utils/s3FileManagerExample.d.ts.map +1 -0
- package/lib/typescript/utils/s3FileManagerRN.d.ts +104 -0
- package/lib/typescript/utils/s3FileManagerRN.d.ts.map +1 -0
- package/package.json +3 -1
- package/src/core/OxyServices.ts +881 -46
- package/src/core/index.ts +9 -24
- package/src/index.ts +17 -1
- package/src/ui/screens/FileManagementScreen.tsx +12 -12
- package/src/ui/screens/ProfileScreen.tsx +3 -3
- package/src/ui/screens/SignInScreen.tsx +1 -1
- package/src/ui/screens/karma/KarmaCenterScreen.tsx +2 -2
- package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +1 -1
- package/src/ui/screens/karma/KarmaRulesScreen.tsx +1 -1
- package/src/ui/stores/followStore.ts +4 -4
- package/src/utils/s3FileManager.ts +281 -0
- package/src/utils/s3FileManagerExample.ts +432 -0
- package/src/utils/s3FileManagerRN.ts +322 -0
- package/lib/commonjs/core/OxyServicesMain.js +0 -51
- package/lib/commonjs/core/OxyServicesMain.js.map +0 -1
- package/lib/commonjs/core/analytics/AnalyticsService.js +0 -67
- package/lib/commonjs/core/analytics/AnalyticsService.js.map +0 -1
- package/lib/commonjs/core/auth/AuthService.js +0 -538
- package/lib/commonjs/core/auth/AuthService.js.map +0 -1
- package/lib/commonjs/core/devices/DeviceService.js +0 -61
- package/lib/commonjs/core/devices/DeviceService.js.map +0 -1
- package/lib/commonjs/core/files/FileService.js +0 -180
- package/lib/commonjs/core/files/FileService.js.map +0 -1
- package/lib/commonjs/core/karma/KarmaService.js +0 -100
- package/lib/commonjs/core/karma/KarmaService.js.map +0 -1
- package/lib/commonjs/core/locations/LocationService.js +0 -131
- package/lib/commonjs/core/locations/LocationService.js.map +0 -1
- package/lib/commonjs/core/payments/PaymentService.js +0 -124
- package/lib/commonjs/core/payments/PaymentService.js.map +0 -1
- package/lib/commonjs/core/users/UserService.js +0 -234
- package/lib/commonjs/core/users/UserService.js.map +0 -1
- package/lib/module/core/OxyServicesMain.js +0 -47
- package/lib/module/core/OxyServicesMain.js.map +0 -1
- package/lib/module/core/analytics/AnalyticsService.js +0 -62
- package/lib/module/core/analytics/AnalyticsService.js.map +0 -1
- package/lib/module/core/auth/AuthService.js +0 -533
- package/lib/module/core/auth/AuthService.js.map +0 -1
- package/lib/module/core/devices/DeviceService.js +0 -57
- package/lib/module/core/devices/DeviceService.js.map +0 -1
- package/lib/module/core/files/FileService.js +0 -175
- package/lib/module/core/files/FileService.js.map +0 -1
- package/lib/module/core/karma/KarmaService.js +0 -95
- package/lib/module/core/karma/KarmaService.js.map +0 -1
- package/lib/module/core/locations/LocationService.js +0 -127
- package/lib/module/core/locations/LocationService.js.map +0 -1
- package/lib/module/core/payments/PaymentService.js +0 -119
- package/lib/module/core/payments/PaymentService.js.map +0 -1
- package/lib/module/core/users/UserService.js +0 -230
- package/lib/module/core/users/UserService.js.map +0 -1
- package/lib/typescript/core/OxyServicesMain.d.ts +0 -33
- package/lib/typescript/core/OxyServicesMain.d.ts.map +0 -1
- package/lib/typescript/core/analytics/AnalyticsService.d.ts +0 -26
- package/lib/typescript/core/analytics/AnalyticsService.d.ts.map +0 -1
- package/lib/typescript/core/auth/AuthService.d.ts +0 -165
- package/lib/typescript/core/auth/AuthService.d.ts.map +0 -1
- package/lib/typescript/core/devices/DeviceService.d.ts +0 -20
- package/lib/typescript/core/devices/DeviceService.d.ts.map +0 -1
- package/lib/typescript/core/files/FileService.d.ts +0 -59
- package/lib/typescript/core/files/FileService.d.ts.map +0 -1
- package/lib/typescript/core/karma/KarmaService.d.ts +0 -50
- package/lib/typescript/core/karma/KarmaService.d.ts.map +0 -1
- package/lib/typescript/core/locations/LocationService.d.ts +0 -39
- package/lib/typescript/core/locations/LocationService.d.ts.map +0 -1
- package/lib/typescript/core/payments/PaymentService.d.ts +0 -50
- package/lib/typescript/core/payments/PaymentService.d.ts.map +0 -1
- package/lib/typescript/core/users/UserService.d.ts +0 -111
- package/lib/typescript/core/users/UserService.d.ts.map +0 -1
- package/src/core/OxyServicesMain.ts +0 -57
- package/src/core/analytics/AnalyticsService.ts +0 -64
- package/src/core/auth/AuthService.ts +0 -560
- package/src/core/devices/DeviceService.ts +0 -55
- package/src/core/files/FileService.ts +0 -198
- package/src/core/karma/KarmaService.ts +0 -104
- package/src/core/locations/LocationService.ts +0 -141
- package/src/core/payments/PaymentService.ts +0 -133
- package/src/core/users/UserService.ts +0 -241
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S3 File Management Examples
|
|
3
|
+
*
|
|
4
|
+
* This file demonstrates how to use the S3 file management functionality
|
|
5
|
+
* in both web and React Native environments.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
S3FileManager,
|
|
10
|
+
createS3FileManager,
|
|
11
|
+
S3Config,
|
|
12
|
+
UploadOptions
|
|
13
|
+
} from './s3FileManager';
|
|
14
|
+
import {
|
|
15
|
+
S3FileManagerRN,
|
|
16
|
+
createS3FileManagerRN,
|
|
17
|
+
RNFile
|
|
18
|
+
} from './s3FileManagerRN';
|
|
19
|
+
|
|
20
|
+
// Example configuration
|
|
21
|
+
const s3Config: S3Config = {
|
|
22
|
+
region: 'us-east-1',
|
|
23
|
+
accessKeyId: 'your-access-key-id',
|
|
24
|
+
secretAccessKey: 'your-secret-access-key',
|
|
25
|
+
bucketName: 'your-bucket-name',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// WEB ENVIRONMENT EXAMPLES
|
|
30
|
+
// ============================================================================
|
|
31
|
+
|
|
32
|
+
export class WebFileManagerExample {
|
|
33
|
+
private s3Manager: S3FileManager;
|
|
34
|
+
|
|
35
|
+
constructor() {
|
|
36
|
+
this.s3Manager = createS3FileManager(s3Config);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Example: Upload a file from web form
|
|
41
|
+
*/
|
|
42
|
+
async uploadFileFromForm(fileInput: HTMLInputElement): Promise<string> {
|
|
43
|
+
const file = fileInput.files?.[0];
|
|
44
|
+
if (!file) {
|
|
45
|
+
throw new Error('No file selected');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const key = `uploads/${Date.now()}-${file.name}`;
|
|
49
|
+
const uploadOptions: UploadOptions = {
|
|
50
|
+
contentType: file.type,
|
|
51
|
+
metadata: {
|
|
52
|
+
originalName: file.name,
|
|
53
|
+
uploadedBy: 'web-user',
|
|
54
|
+
uploadedAt: new Date().toISOString(),
|
|
55
|
+
},
|
|
56
|
+
publicRead: false,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const url = await this.s3Manager.uploadFile(key, file, uploadOptions);
|
|
61
|
+
console.log('File uploaded successfully:', url);
|
|
62
|
+
return url;
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error('Upload failed:', error);
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Example: Upload multiple files
|
|
71
|
+
*/
|
|
72
|
+
async uploadMultipleFiles(fileList: FileList): Promise<string[]> {
|
|
73
|
+
const files = Array.from(fileList).map(file => ({
|
|
74
|
+
key: `uploads/${Date.now()}-${file.name}`,
|
|
75
|
+
file,
|
|
76
|
+
options: {
|
|
77
|
+
contentType: file.type,
|
|
78
|
+
metadata: {
|
|
79
|
+
originalName: file.name,
|
|
80
|
+
uploadedBy: 'web-user',
|
|
81
|
+
uploadedAt: new Date().toISOString(),
|
|
82
|
+
},
|
|
83
|
+
publicRead: false,
|
|
84
|
+
} as UploadOptions,
|
|
85
|
+
}));
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const urls = await this.s3Manager.uploadMultipleFiles(files);
|
|
89
|
+
console.log('Files uploaded successfully:', urls);
|
|
90
|
+
return urls;
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error('Upload failed:', error);
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Example: Download a file
|
|
99
|
+
*/
|
|
100
|
+
async downloadFile(key: string): Promise<void> {
|
|
101
|
+
try {
|
|
102
|
+
const buffer = await this.s3Manager.downloadFile(key);
|
|
103
|
+
|
|
104
|
+
// Create a blob and download link
|
|
105
|
+
const blob = new Blob([buffer]);
|
|
106
|
+
const url = URL.createObjectURL(blob);
|
|
107
|
+
const a = document.createElement('a');
|
|
108
|
+
a.href = url;
|
|
109
|
+
a.download = key.split('/').pop() || 'download';
|
|
110
|
+
document.body.appendChild(a);
|
|
111
|
+
a.click();
|
|
112
|
+
document.body.removeChild(a);
|
|
113
|
+
URL.revokeObjectURL(url);
|
|
114
|
+
|
|
115
|
+
console.log('File downloaded successfully');
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.error('Download failed:', error);
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Example: Get presigned URLs
|
|
124
|
+
*/
|
|
125
|
+
async getPresignedUrls(key: string): Promise<{ upload: string; download: string }> {
|
|
126
|
+
try {
|
|
127
|
+
const uploadUrl = await this.s3Manager.getPresignedUploadUrl(key, 'application/octet-stream');
|
|
128
|
+
const downloadUrl = await this.s3Manager.getPresignedDownloadUrl(key);
|
|
129
|
+
|
|
130
|
+
return { upload: uploadUrl, download: downloadUrl };
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.error('Failed to get presigned URLs:', error);
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Example: List files with pagination
|
|
139
|
+
*/
|
|
140
|
+
async listFiles(prefix: string = '', maxKeys: number = 50): Promise<void> {
|
|
141
|
+
try {
|
|
142
|
+
const files = await this.s3Manager.listFiles(prefix, maxKeys);
|
|
143
|
+
console.log('Files found:', files);
|
|
144
|
+
|
|
145
|
+
files.forEach(file => {
|
|
146
|
+
console.log(`- ${file.key} (${file.size} bytes, modified: ${file.lastModified})`);
|
|
147
|
+
});
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.error('Failed to list files:', error);
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Example: File operations (copy, move, delete)
|
|
156
|
+
*/
|
|
157
|
+
async performFileOperations(): Promise<void> {
|
|
158
|
+
const sourceKey = 'uploads/source-file.txt';
|
|
159
|
+
const destKey = 'uploads/destination-file.txt';
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
// Copy file
|
|
163
|
+
await this.s3Manager.copyFile(sourceKey, destKey);
|
|
164
|
+
console.log('File copied successfully');
|
|
165
|
+
|
|
166
|
+
// Move file
|
|
167
|
+
await this.s3Manager.moveFile(destKey, 'uploads/moved-file.txt');
|
|
168
|
+
console.log('File moved successfully');
|
|
169
|
+
|
|
170
|
+
// Delete file
|
|
171
|
+
await this.s3Manager.deleteFile('uploads/moved-file.txt');
|
|
172
|
+
console.log('File deleted successfully');
|
|
173
|
+
} catch (error) {
|
|
174
|
+
console.error('File operation failed:', error);
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// ============================================================================
|
|
181
|
+
// REACT NATIVE ENVIRONMENT EXAMPLES
|
|
182
|
+
// ============================================================================
|
|
183
|
+
|
|
184
|
+
export class ReactNativeFileManagerExample {
|
|
185
|
+
private s3Manager: S3FileManagerRN;
|
|
186
|
+
|
|
187
|
+
constructor() {
|
|
188
|
+
this.s3Manager = createS3FileManagerRN(s3Config);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Example: Upload a file from React Native
|
|
193
|
+
*/
|
|
194
|
+
async uploadFileFromRN(fileInfo: RNFile): Promise<string> {
|
|
195
|
+
const key = `uploads/${Date.now()}-${fileInfo.name}`;
|
|
196
|
+
const uploadOptions: UploadOptions = {
|
|
197
|
+
contentType: fileInfo.type || 'application/octet-stream',
|
|
198
|
+
metadata: {
|
|
199
|
+
originalName: fileInfo.name,
|
|
200
|
+
uploadedBy: 'rn-user',
|
|
201
|
+
uploadedAt: new Date().toISOString(),
|
|
202
|
+
fileSize: fileInfo.size?.toString() || '0',
|
|
203
|
+
},
|
|
204
|
+
publicRead: false,
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
const url = await this.s3Manager.uploadFile(key, fileInfo, uploadOptions);
|
|
209
|
+
console.log('File uploaded successfully:', url);
|
|
210
|
+
return url;
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.error('Upload failed:', error);
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Example: Upload image with size validation
|
|
219
|
+
*/
|
|
220
|
+
async uploadImageWithValidation(fileInfo: RNFile, maxSize: number = 5 * 1024 * 1024): Promise<string> {
|
|
221
|
+
// Get file size
|
|
222
|
+
const fileSize = await this.s3Manager.getFileSize(fileInfo);
|
|
223
|
+
|
|
224
|
+
if (fileSize > maxSize) {
|
|
225
|
+
throw new Error(`File size (${fileSize} bytes) exceeds maximum allowed size (${maxSize} bytes)`);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const key = `images/${Date.now()}-${fileInfo.name}`;
|
|
229
|
+
const uploadOptions: UploadOptions = {
|
|
230
|
+
contentType: fileInfo.type || 'image/jpeg',
|
|
231
|
+
metadata: {
|
|
232
|
+
originalName: fileInfo.name,
|
|
233
|
+
uploadedBy: 'rn-user',
|
|
234
|
+
uploadedAt: new Date().toISOString(),
|
|
235
|
+
fileSize: fileSize.toString(),
|
|
236
|
+
category: 'image',
|
|
237
|
+
},
|
|
238
|
+
publicRead: true, // Images are often public
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
try {
|
|
242
|
+
const url = await this.s3Manager.uploadImage(key, fileInfo, uploadOptions);
|
|
243
|
+
console.log('Image uploaded successfully:', url);
|
|
244
|
+
return url;
|
|
245
|
+
} catch (error) {
|
|
246
|
+
console.error('Image upload failed:', error);
|
|
247
|
+
throw error;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Example: Download file to React Native
|
|
253
|
+
*/
|
|
254
|
+
async downloadFileToRN(key: string): Promise<Buffer> {
|
|
255
|
+
try {
|
|
256
|
+
const buffer = await this.s3Manager.downloadFile(key);
|
|
257
|
+
console.log('File downloaded successfully, size:', buffer.length);
|
|
258
|
+
return buffer;
|
|
259
|
+
} catch (error) {
|
|
260
|
+
console.error('Download failed:', error);
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Example: Batch operations
|
|
267
|
+
*/
|
|
268
|
+
async performBatchOperations(files: RNFile[]): Promise<void> {
|
|
269
|
+
try {
|
|
270
|
+
// Upload multiple files
|
|
271
|
+
const uploadPromises = files.map((file, index) => {
|
|
272
|
+
const key = `batch-uploads/${Date.now()}-${index}-${file.name}`;
|
|
273
|
+
return this.s3Manager.uploadFile(key, file, {
|
|
274
|
+
metadata: { batchId: Date.now().toString() },
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
const uploadedUrls = await Promise.all(uploadPromises);
|
|
279
|
+
console.log('Batch upload completed:', uploadedUrls);
|
|
280
|
+
|
|
281
|
+
// Delete multiple files (example with keys)
|
|
282
|
+
const keysToDelete = uploadedUrls.map((url: string) => {
|
|
283
|
+
const key = url.split('/').pop();
|
|
284
|
+
return `batch-uploads/${key}`;
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
await this.s3Manager.deleteMultipleFiles(keysToDelete);
|
|
288
|
+
console.log('Batch delete completed');
|
|
289
|
+
} catch (error) {
|
|
290
|
+
console.error('Batch operations failed:', error);
|
|
291
|
+
throw error;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ============================================================================
|
|
297
|
+
// USAGE EXAMPLES
|
|
298
|
+
// ============================================================================
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Example usage in a React component
|
|
302
|
+
*/
|
|
303
|
+
export const useS3FileManager = () => {
|
|
304
|
+
const webManager = new WebFileManagerExample();
|
|
305
|
+
const rnManager = new ReactNativeFileManagerExample();
|
|
306
|
+
|
|
307
|
+
const handleFileUpload = async (file: File | RNFile) => {
|
|
308
|
+
try {
|
|
309
|
+
if ('uri' in file) {
|
|
310
|
+
// React Native file
|
|
311
|
+
return await rnManager.uploadFileFromRN(file);
|
|
312
|
+
} else {
|
|
313
|
+
// Web file
|
|
314
|
+
const mockInput = { files: [file] } as unknown as HTMLInputElement;
|
|
315
|
+
return await webManager.uploadFileFromForm(mockInput);
|
|
316
|
+
}
|
|
317
|
+
} catch (error) {
|
|
318
|
+
console.error('Upload failed:', error);
|
|
319
|
+
throw error;
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const handleFileDownload = async (key: string) => {
|
|
324
|
+
try {
|
|
325
|
+
if (typeof window !== 'undefined') {
|
|
326
|
+
// Web environment
|
|
327
|
+
await webManager.downloadFile(key);
|
|
328
|
+
} else {
|
|
329
|
+
// React Native environment
|
|
330
|
+
const buffer = await rnManager.downloadFileToRN(key);
|
|
331
|
+
// Handle buffer in React Native (save to file system, etc.)
|
|
332
|
+
return buffer;
|
|
333
|
+
}
|
|
334
|
+
} catch (error) {
|
|
335
|
+
console.error('Download failed:', error);
|
|
336
|
+
throw error;
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
return {
|
|
341
|
+
uploadFile: handleFileUpload,
|
|
342
|
+
downloadFile: handleFileDownload,
|
|
343
|
+
listFiles: webManager.listFiles.bind(webManager),
|
|
344
|
+
getPresignedUrls: webManager.getPresignedUrls.bind(webManager),
|
|
345
|
+
};
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Example: Error handling and retry logic
|
|
350
|
+
*/
|
|
351
|
+
export const uploadWithRetry = async (
|
|
352
|
+
s3Manager: S3FileManager | S3FileManagerRN,
|
|
353
|
+
key: string,
|
|
354
|
+
file: File | RNFile | Buffer,
|
|
355
|
+
options: UploadOptions = {},
|
|
356
|
+
maxRetries: number = 3
|
|
357
|
+
): Promise<string> => {
|
|
358
|
+
// Type guard to determine which manager we're using
|
|
359
|
+
const isRNManager = (manager: S3FileManager | S3FileManagerRN): manager is S3FileManagerRN => {
|
|
360
|
+
return 'getFileSize' in manager;
|
|
361
|
+
};
|
|
362
|
+
let lastError: Error | undefined;
|
|
363
|
+
|
|
364
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
365
|
+
try {
|
|
366
|
+
if (isRNManager(s3Manager)) {
|
|
367
|
+
// For React Native manager, ensure file is RNFile
|
|
368
|
+
if ('uri' in file) {
|
|
369
|
+
return await s3Manager.uploadFile(key, file, options);
|
|
370
|
+
} else {
|
|
371
|
+
throw new Error('React Native manager requires RNFile with uri property');
|
|
372
|
+
}
|
|
373
|
+
} else {
|
|
374
|
+
// For web manager, ensure file is not RNFile
|
|
375
|
+
if ('uri' in file) {
|
|
376
|
+
throw new Error('Web manager does not support RNFile');
|
|
377
|
+
} else {
|
|
378
|
+
return await s3Manager.uploadFile(key, file, options);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
} catch (error) {
|
|
382
|
+
lastError = error as Error;
|
|
383
|
+
console.warn(`Upload attempt ${attempt} failed:`, error);
|
|
384
|
+
|
|
385
|
+
if (attempt < maxRetries) {
|
|
386
|
+
// Wait before retrying (exponential backoff)
|
|
387
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
388
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
throw new Error(`Upload failed after ${maxRetries} attempts. Last error: ${lastError?.message || 'Unknown error'}`);
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Example: File validation utilities
|
|
398
|
+
*/
|
|
399
|
+
export const validateFile = (
|
|
400
|
+
file: File | RNFile,
|
|
401
|
+
options: {
|
|
402
|
+
maxSize?: number;
|
|
403
|
+
allowedTypes?: string[];
|
|
404
|
+
allowedExtensions?: string[];
|
|
405
|
+
} = {}
|
|
406
|
+
): { isValid: boolean; errors: string[] } => {
|
|
407
|
+
const errors: string[] = [];
|
|
408
|
+
const { maxSize = 10 * 1024 * 1024, allowedTypes = [], allowedExtensions = [] } = options;
|
|
409
|
+
|
|
410
|
+
// Check file size
|
|
411
|
+
if ('size' in file && file.size && file.size > maxSize) {
|
|
412
|
+
errors.push(`File size (${file.size} bytes) exceeds maximum allowed size (${maxSize} bytes)`);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Check file type
|
|
416
|
+
if ('type' in file && file.type && allowedTypes.length > 0 && !allowedTypes.includes(file.type)) {
|
|
417
|
+
errors.push(`File type (${file.type}) is not allowed`);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Check file extension
|
|
421
|
+
if (allowedExtensions.length > 0) {
|
|
422
|
+
const extension = file.name.split('.').pop()?.toLowerCase();
|
|
423
|
+
if (!extension || !allowedExtensions.includes(`.${extension}`)) {
|
|
424
|
+
errors.push(`File extension (.${extension}) is not allowed`);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return {
|
|
429
|
+
isValid: errors.length === 0,
|
|
430
|
+
errors,
|
|
431
|
+
};
|
|
432
|
+
};
|