@unvired/react-native-unvired-sdk 0.0.28 → 0.0.30

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/BuildNo.txt CHANGED
@@ -1 +1 @@
1
- R-0.000.0028
1
+ R-0.000.0030
@@ -20,8 +20,9 @@ export class DatabaseNative {
20
20
  return {
21
21
  create: async (options, successCallback, errorCallback) => {
22
22
  try {
23
- this.getDatabase(options.name, options.location);
24
- successCallback({ success: true, database: options.name });
23
+ const dbName = options.name || options.userId;
24
+ this.getDatabase(dbName, options.location);
25
+ successCallback({ success: true, database: dbName });
25
26
  }
26
27
  catch (error) {
27
28
  errorCallback(error instanceof Error ? error.message : String(error));
@@ -29,9 +30,11 @@ export class DatabaseNative {
29
30
  },
30
31
  execute: async (options, successCallback, errorCallback) => {
31
32
  try {
32
- const db = this.getDatabase(options.dbName);
33
+ const dbName = options.dbName || options.userId;
34
+ const params = options.params || options.args || [];
35
+ const db = this.getDatabase(dbName);
33
36
  // FIX: Await the result properly
34
- const res = await db.execute(options.query, options.params || []);
37
+ const res = await db.execute(options.query, params);
35
38
  let resultToReturn = [];
36
39
  // Cast to any to avoid TS error "Property '_array' does not exist on type 'never'"
37
40
  const rawRes = res;
@@ -45,13 +45,17 @@ export class BaseLogger {
45
45
  return;
46
46
  const line = this.format(className, methodName, message, level);
47
47
  // console always
48
- /*
49
48
  switch (level) {
50
- case 'debug': console.debug(line); break;
51
- case 'info': console.info(line); break;
52
- case 'error': console.error(line); break;
49
+ case 'debug':
50
+ console.debug(line);
51
+ break;
52
+ case 'info':
53
+ console.info(line);
54
+ break;
55
+ case 'error':
56
+ console.error(line);
57
+ break;
53
58
  }
54
- */
55
59
  await this.impl.writeLine(line, MAX_LOG_SIZE);
56
60
  }
57
61
  // -------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unvired/react-native-unvired-sdk",
3
- "version": "0.0.28",
3
+ "version": "0.0.30",
4
4
  "description": "Unvired SDK for React Native with logging, database, notifications, and file system support",
5
5
  "main": "dist/main.js",
6
6
  "types": "dist/main.d.ts",
@@ -1,107 +0,0 @@
1
- import UnviredWrapper from '@unvired/react-native-wrapper-sdk';
2
-
3
- const wrapper = new UnviredWrapper();
4
- const fileServiceRaw = wrapper.file();
5
-
6
- // Helper to convert ArrayBuffer to string (Native JS - No Buffer Dependency)
7
- function arrayBufferToString(buffer: ArrayBuffer): string {
8
- // Handling small to medium files. For very large files, chunking is needed to avoid stack overflow.
9
- return String.fromCharCode.apply(null, new Uint8Array(buffer) as any);
10
- }
11
-
12
- class SDKFileService {
13
-
14
- // Delegate standard methods
15
- getDocumentDirectoryPath() {
16
- return fileServiceRaw.getDocumentDirectory();
17
- }
18
-
19
- async createFile(fileName: string, content: string): Promise<string> {
20
- const dir = fileServiceRaw.getDocumentDirectory();
21
-
22
- // Ensure dir ends with slash
23
- const path = (dir.endsWith('/') ? dir : dir + '/') + fileName;
24
-
25
- // FIX: React Native Blob implementation has issues with direct ArrayBuffer views in some versions.
26
- // Passing string directly to writeExternalFile allows the underlying Blob([content]) to work
27
- // because Blob([string]) is supported.
28
- const data = content;
29
-
30
- console.log(`[SDKFileService] Creating file ${fileName} at ${path}`);
31
- await fileServiceRaw.writeExternalFile(dir, fileName, data as any);
32
- return path;
33
- }
34
-
35
- async readFile(fileName: string): Promise<string> {
36
- let path = fileName;
37
- // If not absolute path, prepend doc dir
38
- if (!fileName.startsWith('/') && !fileName.startsWith('file://')) {
39
- const dir = fileServiceRaw.getDocumentDirectory();
40
- path = (dir.endsWith('/') ? dir : dir + '/') + fileName;
41
- }
42
-
43
- // Cleaning file:// prefix if present
44
- if (path.startsWith('file://')) {
45
- path = path.replace('file://', '');
46
- }
47
-
48
- console.log(`[SDKFileService] Reading file: ${path}`);
49
- const data = await fileServiceRaw.readExternalFile(path);
50
- return arrayBufferToString(data);
51
- }
52
-
53
- async deleteFile(fileName: string): Promise<void> {
54
- let path = fileName;
55
- if (!fileName.startsWith('/') && !fileName.startsWith('file://')) {
56
- const dir = fileServiceRaw.getDocumentDirectory();
57
- path = (dir.endsWith('/') ? dir : dir + '/') + fileName;
58
- }
59
-
60
- // Cleaning file:// prefix if present
61
- if (path.startsWith('file://')) {
62
- path = path.replace('file://', '');
63
- }
64
-
65
- console.log(`[SDKFileService] Deleting file: ${path}`);
66
- await fileServiceRaw.deleteExternalFile(path);
67
- }
68
-
69
- async listFiles(): Promise<any[]> {
70
- const dir = fileServiceRaw.getDocumentDirectory();
71
- console.log(`[SDKFileService] Listing files in: ${dir}`);
72
-
73
- // Use resolveLocalFileSystemURL to get DirectoryEntry
74
- let dirEntry;
75
- try {
76
- dirEntry = await fileServiceRaw.resolveLocalFileSystemURL(dir);
77
- } catch (e) {
78
- console.error('[SDKFileService] Failed to resolve directory:', e);
79
- return [];
80
- }
81
-
82
- return new Promise((resolve, reject) => {
83
- try {
84
- const reader = dirEntry.createReader();
85
- reader.readEntries((entries: any[]) => {
86
- console.log(`[SDKFileService] Found ${entries.length} entries`);
87
- const mapped = entries.map(e => ({
88
- uri: e.nativeURL || e.fullPath,
89
- name: e.name,
90
- isDirectory: e.isDirectory,
91
- size: 0,
92
- modificationTime: Date.now() / 1000
93
- }));
94
- resolve(mapped);
95
- }, (err: any) => {
96
- console.error('[SDKFileService] Failed to list files (readEntries):', err);
97
- resolve([]); // Don't crash UI
98
- });
99
- } catch (e) {
100
- console.error('[SDKFileService] Exception in listFiles:', e);
101
- resolve([]);
102
- }
103
- });
104
- }
105
- }
106
-
107
- export default new SDKFileService();
@@ -1,109 +0,0 @@
1
- /**
2
- * Platform Adapter Interface
3
- *
4
- * This interface abstracts platform-specific functionality so that the core SDK
5
- * can work with both Cordova and React Native platforms.
6
- */
7
-
8
- export enum DatabaseType {
9
- FrameworkDb = 'FrameworkDb',
10
- AppDb = 'AppDb'
11
- }
12
-
13
- export interface IDeviceInfo {
14
- platform: string;
15
- model: string;
16
- version: string;
17
- isMobile: boolean;
18
- }
19
-
20
- export interface IFileEntry {
21
- fullPath: string;
22
- nativeURL: string;
23
- isDirectory?: boolean;
24
- remove(callback: () => void, errorCallback: (error: any) => void): void;
25
- removeRecursively(callback: () => void, errorCallback: (error: any) => void): void;
26
- createReader(): IDirectoryReader;
27
- getDirectory?(path: string, options: { create: boolean }, callback: (entry: IFileEntry) => void, errorCallback: (error: any) => void): void;
28
- getFile?(path: string, options: { create: boolean }, callback: (entry: IFileEntry) => void, errorCallback: (error: any) => void): void;
29
- file?(callback: (file: File) => void, errorCallback: (error: any) => void): void;
30
- createWriter?(callback: (writer: any) => void, errorCallback: (error: any) => void): void;
31
- }
32
-
33
- export interface IDirectoryReader {
34
- readEntries(callback: (entries: IFileEntry[]) => void, errorCallback: (error: any) => void): void;
35
- }
36
-
37
- export interface IDatabaseAdapter {
38
- create(options: { userId: string }, successCallback: (result: any) => void, errorCallback: (error: any) => void): void;
39
- execute(options: any, successCallback: (result: any) => void, errorCallback: (error: any) => void): void;
40
- executeStatementOnPath(dbPath: string, sqlQuery: string, callback: (result: any) => void): void;
41
- selectFromPath(dbPath: string, sqlQuery: string, callback: (result: any) => void): void;
42
- createDatabase(dbPath: string, callback: () => void): void;
43
- getDBFilePath(options: { dbType: string }, callback: (path: string) => void): void;
44
- saveWebDB(options: { userId: string }, callback: (result: any) => void, errorCallback: (error: any) => void): void;
45
- exportWebDB(options: { userId: string }, callback: (result: any) => void, errorCallback: (error: any) => void): void;
46
- deleteUserData(options: { userId: string }, callback: () => void, errorCallback: (error: any) => void): void;
47
- }
48
-
49
- export interface IPushNotificationAdapter {
50
- requestPermission(options?: { forceShow: boolean }): Promise<void>;
51
- getToken(): Promise<string>;
52
- onTokenRefresh(callback: (token: string) => void): void;
53
- onMessage(callback: (payload: any) => void): void;
54
- onBackgroundMessage(callback: (payload: any) => void): void;
55
- }
56
-
57
- export interface ILoggerAdapter {
58
- logDebug(sourceClass: string, method: string, message: string): void;
59
- logError(sourceClass: string, method: string, message: string): void;
60
- logInfo(sourceClass: string, method: string, message: string): void;
61
- setLogLevel(logLevel: string): void;
62
- getLogFileURL(): Promise<string>;
63
- getLogFileContent(): Promise<string>;
64
- getBackupLogFileContent(): Promise<string>;
65
- clearLogFile(): void;
66
- }
67
-
68
- export interface IStorageAdapter {
69
- getItem(key: string): void;
70
- setItem(key: string, value: string): void;
71
- removeItem(key: string): void;
72
- clear(): void;
73
- }
74
-
75
-
76
-
77
- export interface ILocalStorageAdapter {
78
- getItem(key: string): void;
79
- setItem(key: string, value: string): void;
80
- removeItem(key: string): void;
81
- clear(): void;
82
- }
83
- /**
84
- * Main Platform Adapter Interface
85
- */
86
- export interface PlatformInterface {
87
- // Device Information
88
- getDeviceInfo(): IDeviceInfo;
89
- getPlatform(): string;
90
- getFrontendType(): string;
91
- getDocumentDirectory(): string;
92
-
93
- // File System Operations
94
- resolveLocalFileSystemURL(url: string): Promise<IFileEntry>;
95
- getFolderBasedOnUserId(userId: string): Promise<string>;
96
- deleteUserFolder(userId: string): Promise<void>;
97
-
98
- // Database Operations
99
- getDatabaseAdapter(): IDatabaseAdapter;
100
-
101
- // Push Notifications
102
- getPushNotificationAdapter(): IPushNotificationAdapter | null;
103
-
104
- // Logging
105
- getLoggerAdapter(): ILoggerAdapter;
106
-
107
- // Storage
108
- getStorageAdapter(): IStorageAdapter;
109
- }
@@ -1,143 +0,0 @@
1
- import { DeviceInfo, DatabaseManager, LocalStorage, logger, LogLevel, PushNotification, FileSystem } from '@unvired/react-native-unvired-sdk';
2
- import { PlatformInterface, IDeviceInfo, IFileEntry, IDatabaseAdapter, IPushNotificationAdapter, ILoggerAdapter, IStorageAdapter } from './PlatformInterface';
3
-
4
- export class ReactNativePlatformAdapter implements PlatformInterface {
5
-
6
- getDeviceInfo(): IDeviceInfo {
7
- return DeviceInfo.getDeviceInfo();
8
- }
9
-
10
- getPlatform(): string {
11
- return DeviceInfo.getPlatform();
12
- }
13
-
14
- getFrontendType(): string {
15
- return DeviceInfo.getFrontendType();
16
- }
17
-
18
- getDocumentDirectory(): string {
19
- return FileSystem.getDocumentDirectory();
20
- }
21
-
22
- resolveLocalFileSystemURL(url: string): Promise<IFileEntry> {
23
- return FileSystem.resolveLocalFileSystemURL(url);
24
- }
25
-
26
- async getFolderBasedOnUserId(userId: string): Promise<string> {
27
- return await FileSystem.getFolderBasedOnUserId(userId);
28
- }
29
-
30
- async deleteUserFolder(userId: string): Promise<void> {
31
- await FileSystem.deleteUserFolder(userId);
32
- }
33
-
34
- getDatabaseAdapter(): IDatabaseAdapter {
35
- return {
36
- create: (options: { userId: string }, successCallback, errorCallback) => {
37
- // Map userId to dbName or pass appropriate options
38
- DatabaseManager.getDatabaseAdapter().create({ name: options.userId }, successCallback, errorCallback);
39
- },
40
- execute: (options: any, successCallback, errorCallback) => {
41
- DatabaseManager.getDatabaseAdapter().execute({
42
- dbName: options.userId,
43
- query: options.query,
44
- params: options.params
45
- }, successCallback, errorCallback);
46
- },
47
- executeStatementOnPath: (dbPath, sqlQuery, callback) => {
48
- DatabaseManager.getDatabaseAdapter().executeStatementOnPath(dbPath, sqlQuery, callback);
49
- },
50
- selectFromPath: (dbPath, sqlQuery, callback) => {
51
- DatabaseManager.getDatabaseAdapter().selectFromPath(dbPath, sqlQuery, callback);
52
- },
53
- createDatabase: (dbPath, callback) => {
54
- DatabaseManager.getDatabaseAdapter().createDatabase(dbPath, callback);
55
- },
56
- getDBFilePath: (options: { dbType: string }, callback) => {
57
- DatabaseManager.getDatabaseAdapter().getDBFilePath({ name: options.dbType }, callback);
58
- },
59
- saveWebDB: (options: { userId: string }, callback, errorCallback) => {
60
- const dbName = options.userId;
61
- const data = (options as any).data || {};
62
- DatabaseManager.getDatabaseAdapter().saveWebDB({ dbName, data }, callback, errorCallback);
63
- },
64
- exportWebDB: (options: { userId: string }, callback, errorCallback) => {
65
- DatabaseManager.getDatabaseAdapter().exportWebDB({ dbName: options.userId }, callback, errorCallback);
66
- },
67
- deleteUserData: (options: { userId: string }, callback, errorCallback) => {
68
- DatabaseManager.getDatabaseAdapter().deleteUserData({ dbName: options.userId, userId: options.userId }, callback, errorCallback);
69
- }
70
- };
71
- }
72
-
73
- getPushNotificationAdapter(): IPushNotificationAdapter | null {
74
- try {
75
- const pushNotification = new PushNotification();
76
- return {
77
- requestPermission: async (options = { forceShow: false }) => {
78
- await pushNotification.requestPermission(options);
79
- },
80
- getToken: async () => {
81
- return await pushNotification.getToken();
82
- },
83
- onTokenRefresh: (callback) => {
84
- pushNotification.onTokenRefresh(callback);
85
- },
86
- onMessage: (callback) => {
87
- pushNotification.onMessage(callback);
88
- },
89
- onBackgroundMessage: (callback) => {
90
- pushNotification.onBackgroundMessage(callback);
91
- }
92
- };
93
- } catch (error) {
94
- return null;
95
- }
96
- }
97
-
98
- getLoggerAdapter(): ILoggerAdapter {
99
- return {
100
- logDebug: (sourceClass, method, message) => {
101
- logger.logDebug(sourceClass, method, message);
102
- },
103
- logError: (sourceClass, method, message) => {
104
- logger.logError(sourceClass, method, message);
105
- },
106
- logInfo: (sourceClass, method, message) => {
107
- logger.logInfo(sourceClass, method, message);
108
- },
109
- setLogLevel: (logLevel: LogLevel) => {
110
- logger.setLogLevel(logLevel);
111
- },
112
- getLogFileURL: async () => {
113
- return logger.getLogFileURL();
114
- },
115
- getLogFileContent: async () => {
116
- return logger.getLogFileContent();
117
- },
118
- getBackupLogFileContent: async () => {
119
- return logger.getBackupLogFileContent();
120
- },
121
- clearLogFile: async () => {
122
- logger.clearLogFile();
123
- }
124
- };
125
- }
126
-
127
- getStorageAdapter(): IStorageAdapter {
128
- return {
129
- getItem: (key: string) => {
130
- return LocalStorage.getItem(key);
131
- },
132
- setItem: (key: string, value: string) => {
133
- return LocalStorage.setItem(key, value);
134
- },
135
- removeItem: (key: string) => {
136
- return LocalStorage.removeItem(key);
137
- },
138
- clear: () => {
139
- return LocalStorage.clear();
140
- }
141
- };
142
- }
143
- }
@@ -1,313 +0,0 @@
1
- import { PlatformManager } from '@unvired/unvired-ts-core-sdk';
2
-
3
- export interface IDirectoryReader {
4
- readEntries(successCallback: (entries: IFileEntry[]) => void, errorCallback: (error: any) => void): void;
5
- }
6
-
7
- export interface IFileEntry {
8
- fullPath: string;
9
- nativeURL: string;
10
- isDirectory?: boolean;
11
- remove(callback: () => void, errorCallback: (error: any) => void): void;
12
- removeRecursively(callback: () => void, errorCallback: (error: any) => void): void;
13
- createReader(): IDirectoryReader;
14
- getDirectory?(path: string, options: { create: boolean }, callback: (entry: IFileEntry) => void, errorCallback: (error: any) => void): void;
15
- getFile?(path: string, options: { create: boolean }, callback: (entry: IFileEntry) => void, errorCallback: (error: any) => void): void;
16
- file?(callback: (file: File) => void, errorCallback: (error: any) => void): void;
17
- createWriter?(callback: (writer: any) => void, errorCallback: (error: any) => void): void;
18
- }
19
-
20
- export class FileService {
21
-
22
- getDocumentDirectory(): string {
23
- // @ts-ignore
24
- return PlatformManager.getInstance().getPlatformAdapter().getDocumentDirectory();
25
- }
26
-
27
- resolveLocalFileSystemURL(url: string): Promise<IFileEntry> {
28
- // @ts-ignore
29
- return PlatformManager.getInstance().getPlatformAdapter().resolveLocalFileSystemURL(url);
30
- }
31
-
32
- async getFolderBasedOnUserId(userId: string): Promise<string> {
33
- // @ts-ignore
34
- return await PlatformManager.getInstance().getPlatformAdapter().getFolderBasedOnUserId(userId);
35
- }
36
-
37
- async deleteUserFolder(userId: string): Promise<void> {
38
- // @ts-ignore
39
- await PlatformManager.getInstance().getPlatformAdapter().deleteUserFolder(userId);
40
- }
41
-
42
- /**
43
- * Reads an external file as ArrayBuffer using IFileEntry API
44
- * @param filePath Absolute path to the file
45
- */
46
- async readExternalFile(filePath: string): Promise<ArrayBuffer> {
47
- // Get the file entry
48
- const fileEntry = await this.resolveLocalFileSystemURL(filePath);
49
-
50
- return new Promise((resolve, reject) => {
51
- // Use the file() method to read the file
52
- if (!fileEntry.file) {
53
- reject(new Error('file() method not available on entry'));
54
- return;
55
- }
56
-
57
- fileEntry.file(
58
- async (fileMetadata: any) => {
59
- try {
60
- // Read the file using react-native-fs
61
- const RNFS = await import('react-native-fs');
62
- const content = await RNFS.readFile(fileMetadata.path, 'utf8');
63
-
64
- // Convert string to ArrayBuffer
65
- const encoder = new TextEncoder();
66
- resolve(encoder.encode(content).buffer);
67
- } catch (error) {
68
- reject(error);
69
- }
70
- },
71
- (error: any) => {
72
- reject(error);
73
- }
74
- );
75
- });
76
- }
77
-
78
- /**
79
- * Writes data to an external file using IFileEntry API
80
- * @param filePath Parent directory path
81
- * @param fileName File name
82
- * @param data Data to write (ArrayBuffer or string)
83
- */
84
- async writeExternalFile(filePath: string, fileName: string, data: ArrayBuffer | string): Promise<void> {
85
- // Convert data to string if it's ArrayBuffer
86
- let content: string;
87
- if (data instanceof ArrayBuffer) {
88
- const decoder = new TextDecoder();
89
- content = decoder.decode(data);
90
- } else {
91
- content = data;
92
- }
93
-
94
- // Get the directory entry
95
- const dirEntry = await this.resolveLocalFileSystemURL(filePath);
96
-
97
- return new Promise((resolve, reject) => {
98
- // Get or create the file
99
- if (!dirEntry.getFile) {
100
- reject(new Error('getFile() method not available on directory entry'));
101
- return;
102
- }
103
-
104
- dirEntry.getFile(
105
- fileName,
106
- { create: true },
107
- (fileEntry: IFileEntry) => {
108
- // Create a writer
109
- if (!fileEntry.createWriter) {
110
- reject(new Error('createWriter() method not available on file entry'));
111
- return;
112
- }
113
-
114
- fileEntry.createWriter(
115
- (writer: any) => {
116
- writer.onwriteend = () => {
117
- resolve();
118
- };
119
- writer.onerror = (error: any) => {
120
- reject(error);
121
- };
122
-
123
- // Write the content
124
- writer.write(content);
125
- },
126
- (error: any) => {
127
- reject(error);
128
- }
129
- );
130
- },
131
- (error: any) => {
132
- reject(error);
133
- }
134
- );
135
- });
136
- }
137
-
138
- /**
139
- * Deletes an external file using IFileEntry API
140
- * @param filePath Absolute path to the file
141
- */
142
- async deleteExternalFile(filePath: string): Promise<void> {
143
- const fileEntry = await this.resolveLocalFileSystemURL(filePath);
144
-
145
- return new Promise((resolve, reject) => {
146
- fileEntry.remove(
147
- () => resolve(),
148
- (error: any) => reject(error)
149
- );
150
- });
151
- }
152
-
153
- /**
154
- * Checks if a file exists using IFileEntry API
155
- * @param filePath Absolute path to the file
156
- */
157
- async fileExists(filePath: string): Promise<boolean> {
158
- try {
159
- await this.resolveLocalFileSystemURL(filePath);
160
- return true;
161
- } catch (error) {
162
- return false;
163
- }
164
- }
165
-
166
- /**
167
- * Creates a directory
168
- * @param dirPath Parent directory path
169
- * @param dirName Directory name to create
170
- */
171
- async createDirectory(dirPath: string, dirName: string): Promise<IFileEntry> {
172
- const parentEntry = await this.resolveLocalFileSystemURL(dirPath);
173
-
174
- return new Promise((resolve, reject) => {
175
- if (!parentEntry.getDirectory) {
176
- reject(new Error('getDirectory() method not available on entry'));
177
- return;
178
- }
179
-
180
- parentEntry.getDirectory(
181
- dirName,
182
- { create: true },
183
- (dirEntry: IFileEntry) => resolve(dirEntry),
184
- (error: any) => reject(error)
185
- );
186
- });
187
- }
188
-
189
- /**
190
- * Lists files and directories in a directory
191
- * @param dirPath Directory path to list
192
- */
193
- async listDirectory(dirPath: string): Promise<IFileEntry[]> {
194
- const dirEntry = await this.resolveLocalFileSystemURL(dirPath);
195
-
196
- return new Promise((resolve, reject) => {
197
- const reader = dirEntry.createReader();
198
- reader.readEntries(
199
- (entries: IFileEntry[]) => resolve(entries),
200
- (error: any) => reject(error)
201
- );
202
- });
203
- }
204
-
205
- /**
206
- * Deletes a directory and all its contents
207
- * @param dirPath Directory path to delete
208
- */
209
- async deleteDirectory(dirPath: string): Promise<void> {
210
- const dirEntry = await this.resolveLocalFileSystemURL(dirPath);
211
-
212
- return new Promise((resolve, reject) => {
213
- dirEntry.removeRecursively(
214
- () => resolve(),
215
- (error: any) => reject(error)
216
- );
217
- });
218
- }
219
-
220
- /**
221
- * Copies a file
222
- * @param sourcePath Source file path
223
- * @param destDir Destination directory path
224
- * @param newName New file name (optional, keeps original name if not provided)
225
- */
226
- async copyFile(sourcePath: string, destDir: string, newName?: string): Promise<void> {
227
- // Read source file
228
- const content = await this.readExternalFile(sourcePath);
229
-
230
- // Get source file name if newName not provided
231
- const fileName = newName || sourcePath.split('/').pop() || 'file';
232
-
233
- // Write to destination
234
- await this.writeExternalFile(destDir, fileName, content);
235
- }
236
-
237
- /**
238
- * Moves/renames a file
239
- * @param sourcePath Source file path
240
- * @param destDir Destination directory path
241
- * @param newName New file name (optional, keeps original name if not provided)
242
- */
243
- async moveFile(sourcePath: string, destDir: string, newName?: string): Promise<void> {
244
- // Copy file to destination
245
- await this.copyFile(sourcePath, destDir, newName);
246
-
247
- // Delete source file
248
- await this.deleteExternalFile(sourcePath);
249
- }
250
-
251
- /**
252
- * Gets file information (size, modification date, etc.)
253
- * @param filePath File path
254
- */
255
- async getFileInfo(filePath: string): Promise<any> {
256
- const fileEntry = await this.resolveLocalFileSystemURL(filePath);
257
-
258
- return new Promise((resolve, reject) => {
259
- if (!fileEntry.file) {
260
- reject(new Error('file() method not available on entry'));
261
- return;
262
- }
263
-
264
- fileEntry.file(
265
- (fileMetadata: any) => resolve(fileMetadata),
266
- (error: any) => reject(error)
267
- );
268
- });
269
- }
270
-
271
- /**
272
- * Appends data to an existing file
273
- * @param filePath File path
274
- * @param data Data to append
275
- */
276
- async appendToFile(filePath: string, data: ArrayBuffer | string): Promise<void> {
277
- // Convert data to string if it's ArrayBuffer
278
- let content: string;
279
- if (data instanceof ArrayBuffer) {
280
- const decoder = new TextDecoder();
281
- content = decoder.decode(data);
282
- } else {
283
- content = data;
284
- }
285
-
286
- const fileEntry = await this.resolveLocalFileSystemURL(filePath);
287
-
288
- return new Promise((resolve, reject) => {
289
- if (!fileEntry.createWriter) {
290
- reject(new Error('createWriter() method not available on file entry'));
291
- return;
292
- }
293
-
294
- fileEntry.createWriter(
295
- (writer: any) => {
296
- writer.onwriteend = () => {
297
- resolve();
298
- };
299
- writer.onerror = (error: any) => {
300
- reject(error);
301
- };
302
-
303
- // Append the content
304
- writer.append(content);
305
- },
306
- (error: any) => {
307
- reject(error);
308
- }
309
- );
310
- });
311
- }
312
-
313
- }