@unvired/react-native-unvired-sdk 0.0.25 → 0.0.27

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.0025
1
+ R-0.000.0027
@@ -31,7 +31,7 @@ export class DatabaseNative {
31
31
  try {
32
32
  const db = this.getDatabase(options.dbName);
33
33
  // FIX: Await the result properly
34
- const res = await db.execute(options.query, options.params);
34
+ const res = await db.execute(options.query, options.params || []);
35
35
  let resultToReturn = [];
36
36
  // Cast to any to avoid TS error "Property '_array' does not exist on type 'never'"
37
37
  const rawRes = res;
@@ -6,16 +6,10 @@ import { IDeviceInfo } from './DeviceInfo.types';
6
6
  export declare class BaseDeviceInfo {
7
7
  private static cachedDeviceInfo;
8
8
  /**
9
- * Get comprehensive device information (async)
10
- * Call this once during app initialization to populate cache
9
+ * Get comprehensive device information synchronously
10
+ * Uses synchronous methods from react-native-device-info
11
11
  */
12
- static getDeviceInfo(): Promise<IDeviceInfo>;
13
- /**
14
- * Get device information synchronously (returns cached data)
15
- * Returns loading state if not yet initialized
16
- * Call getDeviceInfo() first to populate cache
17
- */
18
- static getDeviceInfoSync(): IDeviceInfo;
12
+ static getDeviceInfo(): IDeviceInfo;
19
13
  /**
20
14
  * Get platform name
21
15
  */
@@ -8,54 +8,47 @@ import DeviceInfo from 'react-native-device-info';
8
8
  */
9
9
  export class BaseDeviceInfo {
10
10
  /**
11
- * Get comprehensive device information (async)
12
- * Call this once during app initialization to populate cache
11
+ * Get comprehensive device information synchronously
12
+ * Uses synchronous methods from react-native-device-info
13
13
  */
14
- static async getDeviceInfo() {
14
+ static getDeviceInfo() {
15
15
  if (this.cachedDeviceInfo) {
16
16
  return this.cachedDeviceInfo;
17
17
  }
18
18
  try {
19
+ // Use synchronous methods from react-native-device-info
19
20
  const deviceInfo = {
20
21
  platform: Platform.OS,
21
- model: await DeviceInfo.getModel(),
22
+ model: DeviceInfo.getModel(),
22
23
  version: Platform.Version.toString(),
23
24
  isMobile: Platform.OS === 'ios' || Platform.OS === 'android',
24
- manufacturer: await DeviceInfo.getManufacturer(),
25
- uuid: await DeviceInfo.getUniqueId(),
25
+ manufacturer: DeviceInfo.getManufacturerSync(),
26
+ uuid: DeviceInfo.getUniqueIdSync(),
27
+ deviceId: DeviceInfo.getUniqueIdSync(),
28
+ deviceName: DeviceInfo.getDeviceNameSync(),
29
+ brand: DeviceInfo.getBrand(),
30
+ deviceType: DeviceInfo.getDeviceType(),
26
31
  };
27
32
  this.cachedDeviceInfo = deviceInfo;
28
33
  return deviceInfo;
29
34
  }
30
35
  catch (error) {
31
36
  console.error('Error getting device info:', error);
37
+ // Return fallback with synchronous Platform data
32
38
  const fallback = {
33
39
  platform: Platform.OS,
34
40
  model: 'Unknown',
35
41
  version: Platform.Version.toString(),
36
42
  isMobile: Platform.OS === 'ios' || Platform.OS === 'android',
43
+ deviceId: 'N/A',
44
+ deviceName: 'N/A',
45
+ brand: 'N/A',
46
+ deviceType: 'N/A',
37
47
  };
38
48
  this.cachedDeviceInfo = fallback;
39
49
  return fallback;
40
50
  }
41
51
  }
42
- /**
43
- * Get device information synchronously (returns cached data)
44
- * Returns loading state if not yet initialized
45
- * Call getDeviceInfo() first to populate cache
46
- */
47
- static getDeviceInfoSync() {
48
- if (this.cachedDeviceInfo) {
49
- return this.cachedDeviceInfo;
50
- }
51
- // Return immediate fallback while async initialization happens
52
- return {
53
- platform: Platform.OS,
54
- model: 'Loading...',
55
- version: Platform.Version.toString(),
56
- isMobile: Platform.OS === 'ios' || Platform.OS === 'android',
57
- };
58
- }
59
52
  /**
60
53
  * Get platform name
61
54
  */
@@ -8,4 +8,8 @@ export interface IDeviceInfo {
8
8
  isMobile: boolean;
9
9
  manufacturer?: string;
10
10
  uuid?: string;
11
+ deviceId?: string;
12
+ deviceName?: string;
13
+ brand?: string;
14
+ deviceType?: string;
11
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unvired/react-native-unvired-sdk",
3
- "version": "0.0.25",
3
+ "version": "0.0.27",
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",
@@ -0,0 +1,107 @@
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();
@@ -85,7 +85,7 @@ export interface ILocalStorageAdapter {
85
85
  */
86
86
  export interface PlatformInterface {
87
87
  // Device Information
88
- getDeviceInfo(): Promise<IDeviceInfo>;
88
+ getDeviceInfo(): IDeviceInfo;
89
89
  getPlatform(): string;
90
90
  getFrontendType(): string;
91
91
  getDocumentDirectory(): string;
@@ -1,15 +1,10 @@
1
- import { DeviceInfo } from '../src/device-info';
2
- import { DatabaseManager } from '../src/database';
3
- import { LocalStorage } from '../src/local-storage';
4
- import { logger, LogLevel } from '../src/logger';
5
- import { PushNotification } from '../src/push-notification';
6
- import { FileSystem } from '../src/file-system';
1
+ import { DeviceInfo, DatabaseManager, LocalStorage, logger, LogLevel, PushNotification, FileSystem } from '@unvired/react-native-unvired-sdk';
7
2
  import { PlatformInterface, IDeviceInfo, IFileEntry, IDatabaseAdapter, IPushNotificationAdapter, ILoggerAdapter, IStorageAdapter } from './PlatformInterface';
8
3
 
9
4
  export class ReactNativePlatformAdapter implements PlatformInterface {
10
5
 
11
- async getDeviceInfo(): Promise<IDeviceInfo> {
12
- return await DeviceInfo.getDeviceInfo();
6
+ getDeviceInfo(): IDeviceInfo {
7
+ return DeviceInfo.getDeviceInfo();
13
8
  }
14
9
 
15
10
  getPlatform(): string {
@@ -43,7 +38,11 @@ export class ReactNativePlatformAdapter implements PlatformInterface {
43
38
  DatabaseManager.getDatabaseAdapter().create({ name: options.userId }, successCallback, errorCallback);
44
39
  },
45
40
  execute: (options: any, successCallback, errorCallback) => {
46
- DatabaseManager.getDatabaseAdapter().execute(options, successCallback, errorCallback);
41
+ DatabaseManager.getDatabaseAdapter().execute({
42
+ dbName: options.userId,
43
+ query: options.query,
44
+ params: options.params
45
+ }, successCallback, errorCallback);
47
46
  },
48
47
  executeStatementOnPath: (dbPath, sqlQuery, callback) => {
49
48
  DatabaseManager.getDatabaseAdapter().executeStatementOnPath(dbPath, sqlQuery, callback);
@@ -79,8 +78,7 @@ export class ReactNativePlatformAdapter implements PlatformInterface {
79
78
  await pushNotification.requestPermission(options);
80
79
  },
81
80
  getToken: async () => {
82
- const token = await pushNotification.getToken();
83
- return token || '';
81
+ return await pushNotification.getToken();
84
82
  },
85
83
  onTokenRefresh: (callback) => {
86
84
  pushNotification.onTokenRefresh(callback);
@@ -0,0 +1,313 @@
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
+ }