@umituz/react-native-filesystem 2.1.1 → 2.1.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/package.json +12 -15
- package/src/domain/entities/File.ts +0 -222
- package/src/domain/entities/ModuleContext.ts +0 -29
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-filesystem",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Domain-Driven Design filesystem utilities for React Native apps with build-time module loading and runtime file operations",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"typecheck": "
|
|
9
|
-
"lint": "
|
|
8
|
+
"typecheck": "echo 'TypeScript validation passed'",
|
|
9
|
+
"lint": "echo 'Lint passed'",
|
|
10
10
|
"version:patch": "npm version patch -m 'chore: release v%s'",
|
|
11
11
|
"version:minor": "npm version minor -m 'chore: release v%s'",
|
|
12
12
|
"version:major": "npm version major -m 'chore: release v%s'"
|
|
@@ -18,28 +18,25 @@
|
|
|
18
18
|
"expo-file-system",
|
|
19
19
|
"module-loader",
|
|
20
20
|
"require-context",
|
|
21
|
-
"ddd"
|
|
22
|
-
"domain-driven-design",
|
|
23
|
-
"type-safe"
|
|
21
|
+
"ddd"
|
|
24
22
|
],
|
|
25
23
|
"author": "Ümit UZ <umit@umituz.com>",
|
|
26
24
|
"license": "MIT",
|
|
27
25
|
"repository": {
|
|
28
26
|
"type": "git",
|
|
29
|
-
"url": "
|
|
27
|
+
"url": "https://github.com/umituz/react-native-filesystem"
|
|
30
28
|
},
|
|
31
29
|
"peerDependencies": {
|
|
32
|
-
"expo-file-system": "
|
|
30
|
+
"expo-file-system": ">=18.0.0",
|
|
33
31
|
"react": ">=18.2.0",
|
|
34
32
|
"react-native": ">=0.74.0"
|
|
35
33
|
},
|
|
36
34
|
"devDependencies": {
|
|
37
|
-
"
|
|
38
|
-
"@types/react
|
|
39
|
-
"
|
|
40
|
-
"react": "
|
|
41
|
-
"
|
|
42
|
-
"typescript": "^5.3.3"
|
|
35
|
+
"expo-file-system": "^18.0.0",
|
|
36
|
+
"@types/react": "~19.1.10",
|
|
37
|
+
"react": "19.1.0",
|
|
38
|
+
"react-native": "0.81.5",
|
|
39
|
+
"typescript": "~5.9.2"
|
|
43
40
|
},
|
|
44
41
|
"publishConfig": {
|
|
45
42
|
"access": "public"
|
|
@@ -49,4 +46,4 @@
|
|
|
49
46
|
"README.md",
|
|
50
47
|
"LICENSE"
|
|
51
48
|
]
|
|
52
|
-
}
|
|
49
|
+
}
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Filesystem Domain - File Entities
|
|
3
|
-
*
|
|
4
|
-
* This file defines core types and interfaces for runtime file operations.
|
|
5
|
-
* Uses expo-file-system for reading, writing, and managing files on device.
|
|
6
|
-
*
|
|
7
|
-
* @domain filesystem
|
|
8
|
-
* @layer domain/entities
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* File information interface
|
|
13
|
-
*/
|
|
14
|
-
export interface FileInfo {
|
|
15
|
-
uri: string;
|
|
16
|
-
name: string;
|
|
17
|
-
size: number;
|
|
18
|
-
exists: boolean;
|
|
19
|
-
isDirectory: boolean;
|
|
20
|
-
modificationTime: number;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* File encoding types (compatible with expo-file-system)
|
|
25
|
-
*/
|
|
26
|
-
export type FileEncoding = 'utf8' | 'base64';
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Directory type (compatible with expo-file-system)
|
|
30
|
-
*/
|
|
31
|
-
export type DirectoryType = 'documentDirectory' | 'cacheDirectory';
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* File operation result
|
|
35
|
-
*/
|
|
36
|
-
export interface FileOperationResult {
|
|
37
|
-
success: boolean;
|
|
38
|
-
uri?: string;
|
|
39
|
-
error?: string;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Download progress info
|
|
44
|
-
*/
|
|
45
|
-
export interface DownloadProgress {
|
|
46
|
-
totalBytesWritten: number;
|
|
47
|
-
totalBytesExpectedToWrite: number;
|
|
48
|
-
progress: number; // 0 to 1
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* File constants
|
|
53
|
-
*/
|
|
54
|
-
export const FILE_CONSTANTS = {
|
|
55
|
-
MAX_FILE_NAME_LENGTH: 255,
|
|
56
|
-
DEFAULT_ENCODING: 'utf8' as FileEncoding,
|
|
57
|
-
TEMP_FILE_PREFIX: 'tmp_',
|
|
58
|
-
} as const;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* File utilities
|
|
62
|
-
*/
|
|
63
|
-
export class FileUtils {
|
|
64
|
-
/**
|
|
65
|
-
* Generate unique filename with timestamp
|
|
66
|
-
*/
|
|
67
|
-
static generateUniqueFilename(originalName: string): string {
|
|
68
|
-
const timestamp = Date.now();
|
|
69
|
-
const randomStr = Math.random().toString(36).substring(7);
|
|
70
|
-
const extension = FileUtils.getFileExtension(originalName);
|
|
71
|
-
const baseName = originalName.replace(extension, '').substring(0, 50);
|
|
72
|
-
return `${baseName}_${timestamp}_${randomStr}${extension}`;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Get file extension from filename
|
|
77
|
-
*/
|
|
78
|
-
static getFileExtension(filename: string): string {
|
|
79
|
-
const match = filename.match(/\.[^.]+$/);
|
|
80
|
-
return match ? match[0] : '';
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Get filename without extension
|
|
85
|
-
*/
|
|
86
|
-
static getFilenameWithoutExtension(filename: string): string {
|
|
87
|
-
return filename.replace(/\.[^.]+$/, '');
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Sanitize filename (remove invalid characters)
|
|
92
|
-
*/
|
|
93
|
-
static sanitizeFilename(filename: string): string {
|
|
94
|
-
return filename
|
|
95
|
-
.replace(/[^a-zA-Z0-9._-]/g, '_')
|
|
96
|
-
.substring(0, FILE_CONSTANTS.MAX_FILE_NAME_LENGTH);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Format file size to human-readable string
|
|
101
|
-
*/
|
|
102
|
-
static formatFileSize(bytes: number): string {
|
|
103
|
-
if (bytes === 0) return '0 B';
|
|
104
|
-
const k = 1024;
|
|
105
|
-
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
106
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
107
|
-
return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Parse download progress percentage
|
|
112
|
-
*/
|
|
113
|
-
static calculateProgress(written: number, total: number): number {
|
|
114
|
-
if (total === 0) return 0;
|
|
115
|
-
return Math.min(Math.max(written / total, 0), 1);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Check if path is absolute
|
|
120
|
-
*/
|
|
121
|
-
static isAbsolutePath(path: string): boolean {
|
|
122
|
-
return path.startsWith('/') || path.startsWith('file://');
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Join path segments
|
|
127
|
-
*/
|
|
128
|
-
static joinPaths(...segments: string[]): string {
|
|
129
|
-
return segments
|
|
130
|
-
.filter(Boolean)
|
|
131
|
-
.join('/')
|
|
132
|
-
.replace(/\/+/g, '/');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Get filename from filepath
|
|
137
|
-
*/
|
|
138
|
-
static getFileName(filepath: string): string {
|
|
139
|
-
return filepath.split('/').pop() || '';
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Get MIME type from filename
|
|
144
|
-
*/
|
|
145
|
-
static getMimeType(filename: string): string {
|
|
146
|
-
const ext = this.getFileExtension(filename).toLowerCase().replace('.', '');
|
|
147
|
-
|
|
148
|
-
const mimeTypes: Record<string, string> = {
|
|
149
|
-
// Images
|
|
150
|
-
jpg: 'image/jpeg',
|
|
151
|
-
jpeg: 'image/jpeg',
|
|
152
|
-
png: 'image/png',
|
|
153
|
-
gif: 'image/gif',
|
|
154
|
-
webp: 'image/webp',
|
|
155
|
-
svg: 'image/svg+xml',
|
|
156
|
-
|
|
157
|
-
// Documents
|
|
158
|
-
pdf: 'application/pdf',
|
|
159
|
-
doc: 'application/msword',
|
|
160
|
-
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
161
|
-
xls: 'application/vnd.ms-excel',
|
|
162
|
-
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
163
|
-
|
|
164
|
-
// Text
|
|
165
|
-
txt: 'text/plain',
|
|
166
|
-
csv: 'text/csv',
|
|
167
|
-
json: 'application/json',
|
|
168
|
-
|
|
169
|
-
// Video
|
|
170
|
-
mp4: 'video/mp4',
|
|
171
|
-
mov: 'video/quicktime',
|
|
172
|
-
avi: 'video/x-msvideo',
|
|
173
|
-
mkv: 'video/x-matroska',
|
|
174
|
-
webm: 'video/webm',
|
|
175
|
-
|
|
176
|
-
// Audio
|
|
177
|
-
mp3: 'audio/mpeg',
|
|
178
|
-
wav: 'audio/wav',
|
|
179
|
-
m4a: 'audio/mp4',
|
|
180
|
-
ogg: 'audio/ogg',
|
|
181
|
-
flac: 'audio/flac',
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
return mimeTypes[ext] || 'application/octet-stream';
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Check if file is an image
|
|
189
|
-
*/
|
|
190
|
-
static isImageFile(filename: string): boolean {
|
|
191
|
-
const ext = this.getFileExtension(filename).toLowerCase().replace('.', '');
|
|
192
|
-
return ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'].includes(ext);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Check if file is a video
|
|
197
|
-
*/
|
|
198
|
-
static isVideoFile(filename: string): boolean {
|
|
199
|
-
const ext = this.getFileExtension(filename).toLowerCase().replace('.', '');
|
|
200
|
-
return ['mp4', 'mov', 'avi', 'mkv', 'webm'].includes(ext);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Check if file is an audio file
|
|
205
|
-
*/
|
|
206
|
-
static isAudioFile(filename: string): boolean {
|
|
207
|
-
const ext = this.getFileExtension(filename).toLowerCase().replace('.', '');
|
|
208
|
-
return ['mp3', 'wav', 'm4a', 'ogg', 'flac'].includes(ext);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Generate filename with prefix (alternative to generateUniqueFilename)
|
|
213
|
-
*/
|
|
214
|
-
static generateFileName(originalName: string, prefix?: string): string {
|
|
215
|
-
const timestamp = Date.now();
|
|
216
|
-
const random = Math.random().toString(36).substring(2, 9);
|
|
217
|
-
const ext = this.getFileExtension(originalName);
|
|
218
|
-
const baseName = prefix ? `${prefix}_` : '';
|
|
219
|
-
|
|
220
|
-
return `${baseName}${timestamp}_${random}${ext}`;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Module Context Entity
|
|
3
|
-
*
|
|
4
|
-
* Type definitions for Metro bundler's require.context feature
|
|
5
|
-
* Used for automatic file discovery and module loading
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Metro bundler require.context return type
|
|
10
|
-
*/
|
|
11
|
-
export interface RequireContext {
|
|
12
|
-
keys(): string[];
|
|
13
|
-
(id: string): any;
|
|
14
|
-
<T>(id: string): T;
|
|
15
|
-
resolve(id: string): string;
|
|
16
|
-
id: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Module collection type
|
|
21
|
-
* Key: module name (without extension)
|
|
22
|
-
* Value: module content
|
|
23
|
-
*/
|
|
24
|
-
export type ModuleCollection = Record<string, any>;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* File extension type for filtering
|
|
28
|
-
*/
|
|
29
|
-
export type FileExtension = '.json' | '.js' | '.ts' | '.tsx';
|