@unvired/react-native-unvired-sdk 0.0.14 → 0.0.16

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.
@@ -0,0 +1,179 @@
1
+ import * as RNFS from 'react-native-fs';
2
+ /**
3
+ * DirectoryReader implementation for React Native
4
+ * Wraps RNFS.readDir to match the Cordova DirectoryReader interface
5
+ */
6
+ export class RNDirectoryReader {
7
+ constructor(dirPath) {
8
+ this.dirPath = dirPath;
9
+ }
10
+ readEntries(callback, errorCallback) {
11
+ RNFS.readDir(this.dirPath)
12
+ .then(items => {
13
+ const entries = items.map(item => new RNFileEntry(item.path, item.isDirectory()));
14
+ callback(entries);
15
+ })
16
+ .catch(errorCallback);
17
+ }
18
+ }
19
+ /**
20
+ * FileEntry implementation for React Native
21
+ * Wraps react-native-fs to match the Cordova FileEntry interface
22
+ */
23
+ export class RNFileEntry {
24
+ constructor(path, isDirectory = false) {
25
+ this.fullPath = path;
26
+ this.nativeURL = `file://${path}`;
27
+ this.isDirectory = isDirectory;
28
+ this.isFile = !isDirectory;
29
+ this.name = path.split('/').pop() || '';
30
+ this.filesystem = null;
31
+ }
32
+ /**
33
+ * Remove a file or empty directory
34
+ */
35
+ remove(callback, errorCallback) {
36
+ RNFS.unlink(this.fullPath)
37
+ .then(() => callback())
38
+ .catch(errorCallback);
39
+ }
40
+ /**
41
+ * Remove a directory and all its contents recursively
42
+ */
43
+ removeRecursively(callback, errorCallback) {
44
+ // RNFS.unlink works recursively for directories
45
+ RNFS.unlink(this.fullPath)
46
+ .then(() => callback())
47
+ .catch(errorCallback);
48
+ }
49
+ /**
50
+ * Create a directory reader for reading directory contents
51
+ */
52
+ createReader() {
53
+ return new RNDirectoryReader(this.fullPath);
54
+ }
55
+ /**
56
+ * Get or create a subdirectory
57
+ */
58
+ getDirectory(path, options, callback, errorCallback) {
59
+ const dirPath = `${this.fullPath}/${path}`;
60
+ RNFS.exists(dirPath)
61
+ .then(exists => {
62
+ if (exists) {
63
+ return RNFS.stat(dirPath).then(stats => {
64
+ if (stats.isDirectory()) {
65
+ callback(new RNFileEntry(dirPath, true));
66
+ }
67
+ else {
68
+ errorCallback(new Error('Path exists but is not a directory'));
69
+ }
70
+ });
71
+ }
72
+ else if (options.create) {
73
+ return RNFS.mkdir(dirPath).then(() => {
74
+ callback(new RNFileEntry(dirPath, true));
75
+ });
76
+ }
77
+ else {
78
+ errorCallback(new Error('Directory does not exist'));
79
+ }
80
+ })
81
+ .catch(errorCallback);
82
+ }
83
+ /**
84
+ * Get or create a file
85
+ */
86
+ getFile(path, options, callback, errorCallback) {
87
+ const filePath = `${this.fullPath}/${path}`;
88
+ RNFS.exists(filePath)
89
+ .then(exists => {
90
+ if (exists) {
91
+ return RNFS.stat(filePath).then(stats => {
92
+ if (!stats.isDirectory()) {
93
+ callback(new RNFileEntry(filePath, false));
94
+ }
95
+ else {
96
+ errorCallback(new Error('Path exists but is a directory'));
97
+ }
98
+ });
99
+ }
100
+ else if (options.create) {
101
+ // Create empty file
102
+ return RNFS.writeFile(filePath, '', 'utf8').then(() => {
103
+ callback(new RNFileEntry(filePath, false));
104
+ });
105
+ }
106
+ else {
107
+ errorCallback(new Error('File does not exist'));
108
+ }
109
+ })
110
+ .catch(errorCallback);
111
+ }
112
+ /**
113
+ * Get file metadata
114
+ */
115
+ file(callback, errorCallback) {
116
+ RNFS.stat(this.fullPath)
117
+ .then(stats => {
118
+ // Create a File-like object with metadata
119
+ const fileObject = {
120
+ name: this.fullPath.split('/').pop() || '',
121
+ size: stats.size,
122
+ type: '', // RNFS doesn't provide MIME type directly
123
+ lastModified: new Date(stats.mtime).getTime(),
124
+ lastModifiedDate: new Date(stats.mtime),
125
+ path: this.fullPath,
126
+ };
127
+ callback(fileObject);
128
+ })
129
+ .catch(errorCallback);
130
+ }
131
+ /**
132
+ * Create a file writer for writing to the file
133
+ */
134
+ createWriter(callback, errorCallback) {
135
+ // Create a FileWriter-like object
136
+ const writer = {
137
+ filePath: this.fullPath,
138
+ write: (data) => {
139
+ return RNFS.writeFile(this.fullPath, data, 'utf8')
140
+ .then(() => { if (writer.onwriteend)
141
+ writer.onwriteend(); })
142
+ .catch((err) => { if (writer.onerror)
143
+ writer.onerror(err); });
144
+ },
145
+ append: (data) => {
146
+ return RNFS.appendFile(this.fullPath, data, 'utf8')
147
+ .then(() => { if (writer.onwriteend)
148
+ writer.onwriteend(); })
149
+ .catch((err) => { if (writer.onerror)
150
+ writer.onerror(err); });
151
+ },
152
+ truncate: (size) => {
153
+ // Read file, truncate content, and write back
154
+ return RNFS.readFile(this.fullPath, 'utf8')
155
+ .then(content => {
156
+ const truncated = content.substring(0, size);
157
+ return RNFS.writeFile(this.fullPath, truncated, 'utf8')
158
+ .then(() => { if (writer.onwriteend)
159
+ writer.onwriteend(); });
160
+ })
161
+ .catch((err) => { if (writer.onerror)
162
+ writer.onerror(err); });
163
+ },
164
+ seek: (offset) => {
165
+ // Not directly supported in RNFS
166
+ // This would need to be implemented with read/write operations
167
+ return Promise.resolve();
168
+ },
169
+ onwriteend: null,
170
+ onerror: null
171
+ };
172
+ try {
173
+ callback(writer);
174
+ }
175
+ catch (error) {
176
+ errorCallback(error);
177
+ }
178
+ }
179
+ }
@@ -1,3 +1,3 @@
1
1
  export { FileSystem } from './FileSystem';
2
- export type { IFileEntry } from './FileSystem.types';
2
+ export type { IFileEntry, IDirectoryReader } from './FileSystem.types';
3
3
  export { default } from './FileSystem';
@@ -1,17 +1,17 @@
1
- import * as RNFS from '@dr.pogodin/react-native-fs';
2
- import { IFileEntry } from '../FileSystem.types';
3
- export declare class FileSystemNative {
1
+ import * as RNFS from 'react-native-fs';
2
+ import { IFileEntry, IFileSystem, FileSystemEncoding } from '../FileSystem.types';
3
+ export declare class FileSystemNative implements IFileSystem {
4
4
  getDocumentDirectory(): string;
5
5
  resolveLocalFileSystemURL(url: string): Promise<IFileEntry>;
6
6
  getFolderBasedOnUserId(userId: string): Promise<string>;
7
7
  deleteUserFolder(userId: string): Promise<void>;
8
8
  createDirectory(path: string): Promise<void>;
9
- readFile(path: string, encoding?: RNFS.EncodingT): Promise<string>;
10
- writeFile(path: string, content: string, encoding?: RNFS.EncodingT): Promise<void>;
9
+ readFile(path: string, encoding?: FileSystemEncoding): Promise<string>;
10
+ writeFile(path: string, content: string, encoding?: FileSystemEncoding): Promise<void>;
11
11
  deleteFile(path: string): Promise<void>;
12
12
  exists(path: string): Promise<boolean>;
13
- stat(path: string): Promise<RNFS.StatResultT>;
14
- readDir(path: string): Promise<RNFS.ReadDirResItemT[]>;
13
+ stat(path: string): Promise<RNFS.StatResult>;
14
+ readDir(path: string): Promise<RNFS.ReadDirItem[]>;
15
15
  copyFile(source: string, destination: string): Promise<void>;
16
16
  moveFile(source: string, destination: string): Promise<void>;
17
17
  }
@@ -1,40 +1,52 @@
1
- import * as RNFS from '@dr.pogodin/react-native-fs';
1
+ import * as RNFS from 'react-native-fs';
2
+ import { RNFileEntry } from '../RNFileEntry';
2
3
  export class FileSystemNative {
3
4
  getDocumentDirectory() {
4
5
  return RNFS.DocumentDirectoryPath;
5
6
  }
6
7
  async resolveLocalFileSystemURL(url) {
7
- let normalizedPath = url;
8
- if (normalizedPath.startsWith('file://')) {
9
- normalizedPath = normalizedPath.substring(7);
10
- }
11
- const exists = await RNFS.exists(normalizedPath);
12
- if (!exists) {
13
- throw new Error(`File or directory does not exist: ${normalizedPath}`);
14
- }
15
- const stat = await RNFS.stat(normalizedPath);
16
- const fileName = stat.name || normalizedPath.split('/').pop() || 'unknown';
17
- return {
18
- isFile: stat.isFile(),
19
- isDirectory: stat.isDirectory(),
20
- name: fileName,
21
- fullPath: stat.path,
22
- nativeURL: `file://${stat.path}`,
23
- };
8
+ return new Promise((resolve, reject) => {
9
+ // Remove file:// prefix if present
10
+ const path = url.replace('file://', '');
11
+ RNFS.exists(path)
12
+ .then(exists => {
13
+ if (!exists) {
14
+ reject(new Error(`Path does not exist: ${path}`));
15
+ return;
16
+ }
17
+ return RNFS.stat(path).then(stats => {
18
+ resolve(new RNFileEntry(path, stats.isDirectory()));
19
+ });
20
+ })
21
+ .catch(reject);
22
+ });
24
23
  }
25
24
  async getFolderBasedOnUserId(userId) {
26
- const userFolder = `${RNFS.DocumentDirectoryPath}/users/${userId}`;
27
- const exists = await RNFS.exists(userFolder);
28
- if (!exists) {
29
- await RNFS.mkdir(userFolder, { NSURLIsExcludedFromBackupKey: true });
25
+ const userPath = `${RNFS.DocumentDirectoryPath}/${userId}`;
26
+ try {
27
+ const exists = await RNFS.exists(userPath);
28
+ if (!exists) {
29
+ // Create the directory if it doesn't exist
30
+ await RNFS.mkdir(userPath);
31
+ }
32
+ // Return the native URL format
33
+ return `file://${userPath}`;
34
+ }
35
+ catch (error) {
36
+ throw new Error(`Failed to get/create folder for user ${userId}: ${error}`);
30
37
  }
31
- return userFolder;
32
38
  }
33
39
  async deleteUserFolder(userId) {
34
- const userFolder = `${RNFS.DocumentDirectoryPath}/users/${userId}`;
35
- const exists = await RNFS.exists(userFolder);
36
- if (exists) {
37
- await RNFS.unlink(userFolder);
40
+ const userPath = `${RNFS.DocumentDirectoryPath}/${userId}`;
41
+ try {
42
+ const exists = await RNFS.exists(userPath);
43
+ if (exists) {
44
+ // RNFS.unlink removes directories recursively
45
+ await RNFS.unlink(userPath);
46
+ }
47
+ }
48
+ catch (error) {
49
+ throw new Error(`Failed to delete folder for user ${userId}: ${error}`);
38
50
  }
39
51
  }
40
52
  async createDirectory(path) {
@@ -1,12 +1,12 @@
1
- import { IFileEntry } from '../FileSystem.types';
2
- export declare class FileSystemWeb {
1
+ import { IFileEntry, IFileSystem, FileSystemEncoding } from '../FileSystem.types';
2
+ export declare class FileSystemWeb implements IFileSystem {
3
3
  getDocumentDirectory(): string;
4
4
  resolveLocalFileSystemURL(url: string): Promise<IFileEntry>;
5
5
  getFolderBasedOnUserId(userId: string): Promise<string>;
6
6
  deleteUserFolder(userId: string): Promise<void>;
7
7
  createDirectory(path: string): Promise<void>;
8
- readFile(path: string, encoding?: string): Promise<string>;
9
- writeFile(path: string, content: string, encoding?: string): Promise<void>;
8
+ readFile(path: string, encoding?: FileSystemEncoding): Promise<string>;
9
+ writeFile(path: string, content: string, encoding?: FileSystemEncoding): Promise<void>;
10
10
  deleteFile(path: string): Promise<void>;
11
11
  exists(path: string): Promise<boolean>;
12
12
  stat(path: string): Promise<any>;
@@ -4,14 +4,14 @@ import { Platform } from 'react-native';
4
4
  let RNFS = null;
5
5
  let zip = null;
6
6
  try {
7
- RNFS = require('@dr.pogodin/react-native-fs');
7
+ RNFS = require('react-native-fs');
8
8
  if (!RNFS || !RNFS.DocumentDirectoryPath) {
9
- console.error('❌ @dr.pogodin/react-native-fs is not properly linked. Please run: cd ios && pod install (iOS) or rebuild your Android app.');
9
+ console.error('❌ react-native-fs is not properly linked. Please run: cd ios && pod install (iOS) or rebuild your Android app.');
10
10
  RNFS = null;
11
11
  }
12
12
  }
13
13
  catch (e) {
14
- console.error('❌ @dr.pogodin/react-native-fs module not found. Please install: npm install @dr.pogodin/react-native-fs');
14
+ console.error('❌ react-native-fs module not found. Please install: npm install react-native-fs');
15
15
  }
16
16
  try {
17
17
  const zipModule = require('react-native-zip-archive');
@@ -2,14 +2,14 @@ import * as pako from 'pako';
2
2
  // Import with null safety
3
3
  let RNFS = null;
4
4
  try {
5
- RNFS = require('@dr.pogodin/react-native-fs');
5
+ RNFS = require('react-native-fs');
6
6
  if (!RNFS || !RNFS.DocumentDirectoryPath) {
7
- console.error('❌ @dr.pogodin/react-native-fs is not properly linked.');
7
+ console.error('❌ react-native-fs is not properly linked.');
8
8
  RNFS = null;
9
9
  }
10
10
  }
11
11
  catch (e) {
12
- console.error('❌ @dr.pogodin/react-native-fs module not found.');
12
+ console.error('❌ react-native-fs module not found.');
13
13
  }
14
14
  export class LoggerWindows {
15
15
  constructor() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unvired/react-native-unvired-sdk",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
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",
@@ -24,13 +24,14 @@
24
24
  "author": "Unvired",
25
25
  "license": "UNLICENSED",
26
26
  "peerDependencies": {
27
- "@dr.pogodin/react-native-fs": "^2.36.2",
27
+ "react-native-fs": "^2.20.0",
28
28
  "@react-native-firebase/messaging": "^21.8.1",
29
- "react": ">=16.8.0",
30
- "react-native": ">=0.60.0",
31
- "react-native-device-info": "^14.1.1",
32
- "react-native-sqlite-storage": "^6.0.1",
33
- "react-native-zip-archive": "^7.0.2"
29
+ "react": "19.2.0",
30
+ "react-native": "0.83.1",
31
+ "react-native-device-info": "^15.0.1",
32
+ "@op-engineering/op-sqlite": "^15.2.5",
33
+ "react-native-zip-archive": "^7.0.2",
34
+ "@react-native-async-storage/async-storage": "^2.2.0"
34
35
  },
35
36
  "peerDependenciesMeta": {
36
37
  "@react-native-firebase/messaging": {
@@ -38,17 +39,24 @@
38
39
  }
39
40
  },
40
41
  "devDependencies": {
41
- "@types/react": "^18.0.0",
42
- "@types/react-native": "^0.72.0",
43
- "@types/react-native-sqlite-storage": "^6.0.5",
42
+ "@types/react": "^19.0.0",
43
+ "@types/react-native": "^0.73.0",
44
44
  "@types/sql.js": "^1.4.9",
45
45
  "eslint": "^8.0.0",
46
46
  "jest": "^29.0.0",
47
47
  "prettier": "^3.0.0",
48
- "typescript": "^5.0.0"
48
+ "typescript": "^5.0.0",
49
+ "react-native-fs": "^2.20.0",
50
+ "@op-engineering/op-sqlite": "^15.2.5",
51
+ "react-native-zip-archive": "^7.0.2",
52
+ "@react-native-async-storage/async-storage": "^2.2.0",
53
+ "react-native-device-info": "^15.0.1",
54
+ "@react-native-firebase/messaging": "^21.8.1"
55
+ },
56
+ "engines": {
57
+ "node": ">=22.0.0"
49
58
  },
50
59
  "dependencies": {
51
- "@react-native-async-storage/async-storage": "^2.2.0",
52
60
  "@types/pako": "^2.0.4",
53
61
  "pako": "^2.1.0",
54
62
  "sql.js": "^1.10.3"
@@ -0,0 +1,109 @@
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(): Promise<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
+ }