@magicpixel/rn-mp-client-sdk 1.13.21 → 1.13.23
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 +44 -5
- package/lib/commonjs/common/device-info-helper.js +43 -27
- package/lib/commonjs/common/device-info-helper.js.map +1 -1
- package/lib/commonjs/types/sdk.d.js +2 -0
- package/lib/commonjs/types/sdk.d.js.map +1 -0
- package/lib/module/common/device-info-helper.js +43 -27
- package/lib/module/common/device-info-helper.js.map +1 -1
- package/lib/module/types/sdk.d.js +2 -0
- package/lib/module/types/sdk.d.js.map +1 -0
- package/lib/typescript/src/common/device-info-helper.d.ts +4 -4
- package/package.json +10 -2
- package/scripts/bootstrap.js +29 -0
- package/scripts/postinstall.js +136 -0
- package/src/common/device-info-helper.ts +56 -31
- package/src/types/sdk.d.ts +54 -0
package/README.md
CHANGED
|
@@ -14,16 +14,55 @@ npm install @magicpixel/rn-mp-client-sdk
|
|
|
14
14
|
npm install react-native @react-native-async-storage/async-storage
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
### For Bare React Native
|
|
17
|
+
### For Bare React Native
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Bare React Native apps require additional setup:
|
|
20
20
|
|
|
21
|
+
#### 1. Install Required Dependencies
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
npm install react-native-get-random-values react-native-device-info
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
#### 2. Link Native Modules (Required)
|
|
28
|
+
|
|
29
|
+
**iOS:**
|
|
21
30
|
```sh
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
cd ios && pod install && cd ..
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Android:** Native modules are auto-linked via Gradle.
|
|
35
|
+
|
|
36
|
+
> ⚠️ **Important:** After running `pod install`, you must fully restart the app:
|
|
37
|
+
> 1. Kill the app in the simulator/device
|
|
38
|
+
> 2. Stop Metro bundler (`Ctrl+C`)
|
|
39
|
+
> 3. Restart Metro (`npx react-native start`)
|
|
40
|
+
> 4. Rebuild and launch the app
|
|
41
|
+
>
|
|
42
|
+
> Simply reloading Metro is not sufficient - the native binary must be rebuilt.
|
|
43
|
+
|
|
44
|
+
#### 3. Add Polyfill Import (Required)
|
|
45
|
+
|
|
46
|
+
Add this import at the very top of your app's entry file (`index.js`), **before any other imports**:
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
import 'react-native-get-random-values'; // Must be first import!
|
|
50
|
+
|
|
51
|
+
import {AppRegistry} from 'react-native';
|
|
52
|
+
import App from './App';
|
|
53
|
+
import {name as appName} from './app.json';
|
|
54
|
+
|
|
55
|
+
AppRegistry.registerComponent(appName, () => App);
|
|
24
56
|
```
|
|
25
57
|
|
|
26
|
-
> **
|
|
58
|
+
> ⚠️ **Without this setup, you will see the error:**
|
|
59
|
+
> ```
|
|
60
|
+
> MagicPixel SDK initialization failed: Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'RNGetRandomValues' could not be found.
|
|
61
|
+
> ```
|
|
62
|
+
|
|
63
|
+
The SDK uses ULID for generating unique identifiers, which requires `crypto.getRandomValues()`. This polyfill must be loaded before any other code runs.
|
|
64
|
+
|
|
65
|
+
> **Note**: For Expo managed apps, no additional setup is required - the polyfill is handled automatically.
|
|
27
66
|
|
|
28
67
|
## Quick Start
|
|
29
68
|
|
|
@@ -12,40 +12,55 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
|
|
|
12
12
|
/**
|
|
13
13
|
* Helper class to automatically detect device and app information
|
|
14
14
|
* Supports both Expo and bare React Native:
|
|
15
|
-
* 1. Tries
|
|
16
|
-
* 2. Falls back to
|
|
15
|
+
* 1. Tries react-native-device-info first (works in bare RN and Expo custom builds)
|
|
16
|
+
* 2. Falls back to Expo modules (for Expo Go where native modules don't work)
|
|
17
17
|
* 3. Returns safe defaults if neither is available
|
|
18
18
|
*/
|
|
19
19
|
class DeviceInfoHelper {
|
|
20
20
|
/**
|
|
21
|
-
* Try to load
|
|
22
|
-
*
|
|
21
|
+
* Try to load react-native-device-info first, then Expo modules
|
|
22
|
+
* Uses console.log during init to avoid Logger dependency issues if module loading fails
|
|
23
23
|
*/
|
|
24
24
|
static async initialize() {
|
|
25
25
|
if (this.initialized) return;
|
|
26
26
|
|
|
27
|
-
// Try
|
|
27
|
+
// FIRST: Try react-native-device-info (preferred - works in bare RN and Expo custom builds)
|
|
28
|
+
// This is a direct dependency of the SDK, so it should always be available except in Expo Go
|
|
28
29
|
try {
|
|
29
30
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
30
|
-
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
const rnDeviceInfo = require('react-native-device-info');
|
|
32
|
+
// Validate the module is actually loaded and functional
|
|
33
|
+
if (rnDeviceInfo && typeof (rnDeviceInfo.default || rnDeviceInfo).getVersion === 'function') {
|
|
34
|
+
this.deviceInfo = rnDeviceInfo.default || rnDeviceInfo;
|
|
35
|
+
this.initialized = true;
|
|
36
|
+
// Use console.log to avoid any Logger issues during early init
|
|
37
|
+
console.log('[MagicPixel DeviceInfoHelper] Using react-native-device-info');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
36
40
|
} catch (error) {
|
|
37
|
-
|
|
41
|
+
// react-native-device-info not available (likely Expo Go)
|
|
42
|
+
console.log('[MagicPixel DeviceInfoHelper] react-native-device-info not available, trying Expo modules');
|
|
38
43
|
}
|
|
39
44
|
|
|
40
|
-
// Fall back to
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
// SECOND: Fall back to Expo modules (for Expo Go where native modules don't work)
|
|
46
|
+
try {
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
48
|
+
const expoApp = require('expo-application');
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
50
|
+
const expoDevice = require('expo-device');
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
52
|
+
const expoConst = require('expo-constants');
|
|
53
|
+
|
|
54
|
+
// Validate modules are actually loaded (not undefined placeholders from Metro)
|
|
55
|
+
if (expoApp && expoDevice && expoConst && typeof expoApp.nativeApplicationVersion !== 'undefined') {
|
|
56
|
+
this.expoApplication = expoApp;
|
|
57
|
+
this.expoDevice = expoDevice;
|
|
58
|
+
this.expoConstants = expoConst.default || expoConst;
|
|
59
|
+
console.log('[MagicPixel DeviceInfoHelper] Using Expo modules');
|
|
48
60
|
}
|
|
61
|
+
} catch (error) {
|
|
62
|
+
// Expo modules not available
|
|
63
|
+
console.log('[MagicPixel DeviceInfoHelper] Expo modules not available, using safe defaults');
|
|
49
64
|
}
|
|
50
65
|
this.initialized = true;
|
|
51
66
|
}
|
|
@@ -57,20 +72,21 @@ class DeviceInfoHelper {
|
|
|
57
72
|
static async getAppInfo() {
|
|
58
73
|
await this.initialize();
|
|
59
74
|
try {
|
|
60
|
-
//
|
|
61
|
-
if (this.expoApplication && this.expoDevice) {
|
|
62
|
-
return await this.getAppInfoFromExpo();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Fall back to react-native-device-info
|
|
75
|
+
// Use react-native-device-info if available (preferred)
|
|
66
76
|
if (this.deviceInfo) {
|
|
67
77
|
return await this.getAppInfoFromDeviceInfo();
|
|
68
78
|
}
|
|
69
79
|
|
|
80
|
+
// Fall back to Expo modules (for Expo Go)
|
|
81
|
+
if (this.expoApplication && this.expoDevice) {
|
|
82
|
+
return await this.getAppInfoFromExpo();
|
|
83
|
+
}
|
|
84
|
+
|
|
70
85
|
// Return safe fallback values
|
|
71
86
|
return this.getSafeDefaults();
|
|
72
87
|
} catch (error) {
|
|
73
|
-
|
|
88
|
+
// Use console.log here as well to be safe
|
|
89
|
+
console.error('[MagicPixel DeviceInfoHelper] Error getting device info:', error);
|
|
74
90
|
return this.getSafeDefaults();
|
|
75
91
|
}
|
|
76
92
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_logger","_defineProperty","e","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","DeviceInfoHelper","initialize","initialized","expoApplication","expoDevice","expoConstants","default","Logger","logDbg","error","deviceInfo","logError","getAppInfo","getAppInfoFromExpo","getAppInfoFromDeviceInfo","getSafeDefaults","_Platform$Version","version","nativeApplicationVersion","buildNumber","nativeBuildVersion","packageName","applicationId","app_version","build_number","package_name","device_model_name","modelName","device_manufacturer","manufacturer","device_id","sessionId","os_name","Platform","OS","os_version","osVersion","Version","toString","is_tablet","deviceType","is_emulator","isDevice","uniqueId","bundleId","Promise","all","getVersion","getBuildNumber","getUniqueId","getBundleId","getModel","getManufacturerSync","getSystemVersion","isTablet","isEmulator","_Platform$Version2","getFormattedAppVersion","info","exports"],"sources":["device-info-helper.ts"],"sourcesContent":["import { Platform } from 'react-native';\nimport { Logger } from './logger';\n\ninterface DeviceAppInfo {\n app_version: string;\n build_number: string;\n package_name: string;\n device_model_name: string;\n device_manufacturer: string;\n device_id: string;\n os_name: string;\n os_version: string;\n is_tablet: boolean;\n is_emulator: boolean;\n}\n\n/**\n * Helper class to automatically detect device and app information\n * Supports both Expo and bare React Native:\n * 1. Tries Expo modules first (works in Expo Go)\n * 2. Falls back to react-native-device-info (for bare RN)\n * 3. Returns safe defaults if neither is available\n */\nexport class DeviceInfoHelper {\n private static expoApplication: any = null;\n private static expoDevice: any = null;\n private static expoConstants: any = null;\n private static deviceInfo: any = null;\n private static initialized = false;\n\n /**\n * Try to load Expo modules and react-native-device-info\n * This uses dynamic imports to avoid errors when modules aren't available\n */\n private static async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Try to load Expo modules first (works in Expo Go)\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.expoApplication = require('expo-application');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.expoDevice = require('expo-device');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.expoConstants = require('expo-constants').default;\n Logger.logDbg('Using Expo modules for device info');\n } catch (error) {\n Logger.logDbg(\n 'Expo modules not available, will try react-native-device-info'\n );\n }\n\n // Fall back to react-native-device-info (for bare RN)\n if (!this.expoApplication) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.deviceInfo = require('react-native-device-info').default;\n Logger.logDbg('Using react-native-device-info for device info');\n } catch (error) {\n Logger.logError(\n 'Neither Expo modules nor react-native-device-info available:',\n error\n );\n }\n }\n\n this.initialized = true;\n }\n\n /**\n * Get comprehensive app and device information\n * All methods are async-safe and handle errors gracefully\n */\n static async getAppInfo(): Promise<DeviceAppInfo> {\n await this.initialize();\n\n try {\n // Try Expo modules first\n if (this.expoApplication && this.expoDevice) {\n return await this.getAppInfoFromExpo();\n }\n\n // Fall back to react-native-device-info\n if (this.deviceInfo) {\n return await this.getAppInfoFromDeviceInfo();\n }\n\n // Return safe fallback values\n return this.getSafeDefaults();\n } catch (error) {\n Logger.logError('Error getting device info:', error);\n return this.getSafeDefaults();\n }\n }\n\n /**\n * Get device info using Expo modules (works in Expo Go)\n */\n private static async getAppInfoFromExpo(): Promise<DeviceAppInfo> {\n const version = this.expoApplication.nativeApplicationVersion || 'unknown';\n const buildNumber = this.expoApplication.nativeBuildVersion || 'unknown';\n const packageName = this.expoApplication.applicationId || 'unknown';\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: packageName,\n\n // Device information\n device_model_name: this.expoDevice.modelName || 'unknown',\n device_manufacturer: this.expoDevice.manufacturer || 'unknown',\n device_id: this.expoConstants.sessionId || 'unknown',\n\n // OS information\n os_name: Platform.OS,\n os_version:\n this.expoDevice.osVersion || Platform.Version?.toString() || 'unknown',\n\n // Additional useful info\n // DeviceType enum: UNKNOWN=0, PHONE=1, TABLET=2, DESKTOP=3, TV=4\n is_tablet: this.expoDevice.deviceType === 2, // DeviceType.TABLET = 2\n is_emulator: !this.expoDevice.isDevice,\n };\n }\n\n /**\n * Get device info using react-native-device-info (for bare RN)\n */\n private static async getAppInfoFromDeviceInfo(): Promise<DeviceAppInfo> {\n const [version, buildNumber, uniqueId, bundleId] = await Promise.all([\n this.deviceInfo.getVersion(),\n this.deviceInfo.getBuildNumber(),\n this.deviceInfo.getUniqueId(),\n this.deviceInfo.getBundleId(),\n ]);\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: bundleId,\n\n // Device information\n device_model_name: this.deviceInfo.getModel(),\n device_manufacturer: this.deviceInfo.getManufacturerSync(),\n device_id: uniqueId,\n\n // OS information\n os_name: Platform.OS,\n os_version: this.deviceInfo.getSystemVersion(),\n\n // Additional useful info\n is_tablet: this.deviceInfo.isTablet(),\n is_emulator: await this.deviceInfo.isEmulator(),\n };\n }\n\n /**\n * Safe default values when no device info library is available\n */\n private static getSafeDefaults(): DeviceAppInfo {\n return {\n app_version: 'unknown',\n build_number: 'unknown',\n package_name: 'unknown',\n device_model_name: 'unknown',\n device_manufacturer: 'unknown',\n device_id: 'unknown',\n os_name: Platform.OS,\n os_version: Platform.Version?.toString() || 'unknown',\n is_tablet: false,\n is_emulator: false,\n };\n }\n\n /**\n * Get app version in format: \"1.0.0 (123)\"\n * Combines version and build number for better tracking\n */\n static async getFormattedAppVersion(): Promise<string> {\n try {\n const info = await this.getAppInfo();\n return `${info.app_version} (${info.build_number})`;\n } catch (error) {\n Logger.logError('Error getting formatted app version:', error);\n return 'unknown';\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_logger","_defineProperty","e","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","DeviceInfoHelper","initialize","initialized","rnDeviceInfo","default","getVersion","deviceInfo","console","log","error","expoApp","expoDevice","expoConst","nativeApplicationVersion","expoApplication","expoConstants","getAppInfo","getAppInfoFromDeviceInfo","getAppInfoFromExpo","getSafeDefaults","_Platform$Version","version","buildNumber","nativeBuildVersion","packageName","applicationId","app_version","build_number","package_name","device_model_name","modelName","device_manufacturer","manufacturer","device_id","sessionId","os_name","Platform","OS","os_version","osVersion","Version","toString","is_tablet","deviceType","is_emulator","isDevice","uniqueId","bundleId","Promise","all","getBuildNumber","getUniqueId","getBundleId","getModel","getManufacturerSync","getSystemVersion","isTablet","isEmulator","_Platform$Version2","getFormattedAppVersion","info","Logger","logError","exports"],"sources":["device-info-helper.ts"],"sourcesContent":["import { Platform } from 'react-native';\nimport { Logger } from './logger';\n\ninterface DeviceAppInfo {\n app_version: string;\n build_number: string;\n package_name: string;\n device_model_name: string;\n device_manufacturer: string;\n device_id: string;\n os_name: string;\n os_version: string;\n is_tablet: boolean;\n is_emulator: boolean;\n}\n\n/**\n * Helper class to automatically detect device and app information\n * Supports both Expo and bare React Native:\n * 1. Tries react-native-device-info first (works in bare RN and Expo custom builds)\n * 2. Falls back to Expo modules (for Expo Go where native modules don't work)\n * 3. Returns safe defaults if neither is available\n */\nexport class DeviceInfoHelper {\n private static expoApplication: any = null;\n private static expoDevice: any = null;\n private static expoConstants: any = null;\n private static deviceInfo: any = null;\n private static initialized = false;\n\n /**\n * Try to load react-native-device-info first, then Expo modules\n * Uses console.log during init to avoid Logger dependency issues if module loading fails\n */\n private static async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // FIRST: Try react-native-device-info (preferred - works in bare RN and Expo custom builds)\n // This is a direct dependency of the SDK, so it should always be available except in Expo Go\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const rnDeviceInfo = require('react-native-device-info');\n // Validate the module is actually loaded and functional\n if (\n rnDeviceInfo &&\n typeof (rnDeviceInfo.default || rnDeviceInfo).getVersion === 'function'\n ) {\n this.deviceInfo = rnDeviceInfo.default || rnDeviceInfo;\n this.initialized = true;\n // Use console.log to avoid any Logger issues during early init\n console.log(\n '[MagicPixel DeviceInfoHelper] Using react-native-device-info'\n );\n return;\n }\n } catch (error) {\n // react-native-device-info not available (likely Expo Go)\n console.log(\n '[MagicPixel DeviceInfoHelper] react-native-device-info not available, trying Expo modules'\n );\n }\n\n // SECOND: Fall back to Expo modules (for Expo Go where native modules don't work)\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoApp = require('expo-application');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoDevice = require('expo-device');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoConst = require('expo-constants');\n\n // Validate modules are actually loaded (not undefined placeholders from Metro)\n if (\n expoApp &&\n expoDevice &&\n expoConst &&\n typeof expoApp.nativeApplicationVersion !== 'undefined'\n ) {\n this.expoApplication = expoApp;\n this.expoDevice = expoDevice;\n this.expoConstants = expoConst.default || expoConst;\n console.log('[MagicPixel DeviceInfoHelper] Using Expo modules');\n }\n } catch (error) {\n // Expo modules not available\n console.log(\n '[MagicPixel DeviceInfoHelper] Expo modules not available, using safe defaults'\n );\n }\n\n this.initialized = true;\n }\n\n /**\n * Get comprehensive app and device information\n * All methods are async-safe and handle errors gracefully\n */\n static async getAppInfo(): Promise<DeviceAppInfo> {\n await this.initialize();\n\n try {\n // Use react-native-device-info if available (preferred)\n if (this.deviceInfo) {\n return await this.getAppInfoFromDeviceInfo();\n }\n\n // Fall back to Expo modules (for Expo Go)\n if (this.expoApplication && this.expoDevice) {\n return await this.getAppInfoFromExpo();\n }\n\n // Return safe fallback values\n return this.getSafeDefaults();\n } catch (error) {\n // Use console.log here as well to be safe\n console.error('[MagicPixel DeviceInfoHelper] Error getting device info:', error);\n return this.getSafeDefaults();\n }\n }\n\n /**\n * Get device info using Expo modules (works in Expo Go)\n */\n private static async getAppInfoFromExpo(): Promise<DeviceAppInfo> {\n const version = this.expoApplication.nativeApplicationVersion || 'unknown';\n const buildNumber = this.expoApplication.nativeBuildVersion || 'unknown';\n const packageName = this.expoApplication.applicationId || 'unknown';\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: packageName,\n\n // Device information\n device_model_name: this.expoDevice.modelName || 'unknown',\n device_manufacturer: this.expoDevice.manufacturer || 'unknown',\n device_id: this.expoConstants.sessionId || 'unknown',\n\n // OS information\n os_name: Platform.OS,\n os_version:\n this.expoDevice.osVersion || Platform.Version?.toString() || 'unknown',\n\n // Additional useful info\n // DeviceType enum: UNKNOWN=0, PHONE=1, TABLET=2, DESKTOP=3, TV=4\n is_tablet: this.expoDevice.deviceType === 2, // DeviceType.TABLET = 2\n is_emulator: !this.expoDevice.isDevice,\n };\n }\n\n /**\n * Get device info using react-native-device-info (for bare RN)\n */\n private static async getAppInfoFromDeviceInfo(): Promise<DeviceAppInfo> {\n const [version, buildNumber, uniqueId, bundleId] = await Promise.all([\n this.deviceInfo.getVersion(),\n this.deviceInfo.getBuildNumber(),\n this.deviceInfo.getUniqueId(),\n this.deviceInfo.getBundleId(),\n ]);\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: bundleId,\n\n // Device information\n device_model_name: this.deviceInfo.getModel(),\n device_manufacturer: this.deviceInfo.getManufacturerSync(),\n device_id: uniqueId,\n\n // OS information\n os_name: Platform.OS,\n os_version: this.deviceInfo.getSystemVersion(),\n\n // Additional useful info\n is_tablet: this.deviceInfo.isTablet(),\n is_emulator: await this.deviceInfo.isEmulator(),\n };\n }\n\n /**\n * Safe default values when no device info library is available\n */\n private static getSafeDefaults(): DeviceAppInfo {\n return {\n app_version: 'unknown',\n build_number: 'unknown',\n package_name: 'unknown',\n device_model_name: 'unknown',\n device_manufacturer: 'unknown',\n device_id: 'unknown',\n os_name: Platform.OS,\n os_version: Platform.Version?.toString() || 'unknown',\n is_tablet: false,\n is_emulator: false,\n };\n }\n\n /**\n * Get app version in format: \"1.0.0 (123)\"\n * Combines version and build number for better tracking\n */\n static async getFormattedAppVersion(): Promise<string> {\n try {\n const info = await this.getAppInfo();\n return `${info.app_version} (${info.build_number})`;\n } catch (error) {\n Logger.logError('Error getting formatted app version:', error);\n return 'unknown';\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["sdk.d.ts"],"sourcesContent":["declare module '@magicpixel/rn-mp-client-sdk' {\n interface InitConfig {\n orgId: string;\n env: 'staging' | 'production';\n projectId: string;\n baseUrl: string;\n logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'none';\n eventDeduplicationWindowMs?: number;\n onInitFailure?: (error: Error) => void;\n }\n\n interface UserInfo {\n pid?: string;\n email?: string;\n phone?: string;\n country?: string;\n city?: string;\n state?: string;\n fName?: string;\n lName?: string;\n zip?: string;\n }\n\n interface PageLoadData {\n page_name: string;\n [key: string]: any;\n }\n\n class MagicPixelImpl {\n init(config: InitConfig): void;\n shutdown(): void;\n recordEvent(eventName: string, payload?: Record<string, any>): void;\n recordPageLoad(data: PageLoadData): void;\n setUserInfo(userInfo: UserInfo): void;\n setCustomerInfo(customerInfo: Record<string, any>): void;\n setDeviceInfo(customFields?: Record<string, any>): void;\n setDeepLinkUrl(url: string): void;\n setFirebaseAppInstanceId(id: string): void;\n getDebugId(): Promise<string | null>;\n setDataLayer(data: Record<string, any>): void;\n persistData(key: string, value: any): void;\n clearPersistedData(keys: string[]): void;\n getDataLayer(): Record<string, any>;\n getEventState(): Record<string, any>;\n hasEventHappened(eventName: string): boolean;\n registerEventProcessor(\n eventType: string,\n callback: (event: any) => void\n ): void;\n }\n\n export const MagicPixel: MagicPixelImpl;\n export const MagicPixelEventBus: any;\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -6,40 +6,55 @@ import { Logger } from './logger';
|
|
|
6
6
|
/**
|
|
7
7
|
* Helper class to automatically detect device and app information
|
|
8
8
|
* Supports both Expo and bare React Native:
|
|
9
|
-
* 1. Tries
|
|
10
|
-
* 2. Falls back to
|
|
9
|
+
* 1. Tries react-native-device-info first (works in bare RN and Expo custom builds)
|
|
10
|
+
* 2. Falls back to Expo modules (for Expo Go where native modules don't work)
|
|
11
11
|
* 3. Returns safe defaults if neither is available
|
|
12
12
|
*/
|
|
13
13
|
export class DeviceInfoHelper {
|
|
14
14
|
/**
|
|
15
|
-
* Try to load
|
|
16
|
-
*
|
|
15
|
+
* Try to load react-native-device-info first, then Expo modules
|
|
16
|
+
* Uses console.log during init to avoid Logger dependency issues if module loading fails
|
|
17
17
|
*/
|
|
18
18
|
static async initialize() {
|
|
19
19
|
if (this.initialized) return;
|
|
20
20
|
|
|
21
|
-
// Try
|
|
21
|
+
// FIRST: Try react-native-device-info (preferred - works in bare RN and Expo custom builds)
|
|
22
|
+
// This is a direct dependency of the SDK, so it should always be available except in Expo Go
|
|
22
23
|
try {
|
|
23
24
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
const rnDeviceInfo = require('react-native-device-info');
|
|
26
|
+
// Validate the module is actually loaded and functional
|
|
27
|
+
if (rnDeviceInfo && typeof (rnDeviceInfo.default || rnDeviceInfo).getVersion === 'function') {
|
|
28
|
+
this.deviceInfo = rnDeviceInfo.default || rnDeviceInfo;
|
|
29
|
+
this.initialized = true;
|
|
30
|
+
// Use console.log to avoid any Logger issues during early init
|
|
31
|
+
console.log('[MagicPixel DeviceInfoHelper] Using react-native-device-info');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
30
34
|
} catch (error) {
|
|
31
|
-
|
|
35
|
+
// react-native-device-info not available (likely Expo Go)
|
|
36
|
+
console.log('[MagicPixel DeviceInfoHelper] react-native-device-info not available, trying Expo modules');
|
|
32
37
|
}
|
|
33
38
|
|
|
34
|
-
// Fall back to
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
// SECOND: Fall back to Expo modules (for Expo Go where native modules don't work)
|
|
40
|
+
try {
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
42
|
+
const expoApp = require('expo-application');
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
44
|
+
const expoDevice = require('expo-device');
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
46
|
+
const expoConst = require('expo-constants');
|
|
47
|
+
|
|
48
|
+
// Validate modules are actually loaded (not undefined placeholders from Metro)
|
|
49
|
+
if (expoApp && expoDevice && expoConst && typeof expoApp.nativeApplicationVersion !== 'undefined') {
|
|
50
|
+
this.expoApplication = expoApp;
|
|
51
|
+
this.expoDevice = expoDevice;
|
|
52
|
+
this.expoConstants = expoConst.default || expoConst;
|
|
53
|
+
console.log('[MagicPixel DeviceInfoHelper] Using Expo modules');
|
|
42
54
|
}
|
|
55
|
+
} catch (error) {
|
|
56
|
+
// Expo modules not available
|
|
57
|
+
console.log('[MagicPixel DeviceInfoHelper] Expo modules not available, using safe defaults');
|
|
43
58
|
}
|
|
44
59
|
this.initialized = true;
|
|
45
60
|
}
|
|
@@ -51,20 +66,21 @@ export class DeviceInfoHelper {
|
|
|
51
66
|
static async getAppInfo() {
|
|
52
67
|
await this.initialize();
|
|
53
68
|
try {
|
|
54
|
-
//
|
|
55
|
-
if (this.expoApplication && this.expoDevice) {
|
|
56
|
-
return await this.getAppInfoFromExpo();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Fall back to react-native-device-info
|
|
69
|
+
// Use react-native-device-info if available (preferred)
|
|
60
70
|
if (this.deviceInfo) {
|
|
61
71
|
return await this.getAppInfoFromDeviceInfo();
|
|
62
72
|
}
|
|
63
73
|
|
|
74
|
+
// Fall back to Expo modules (for Expo Go)
|
|
75
|
+
if (this.expoApplication && this.expoDevice) {
|
|
76
|
+
return await this.getAppInfoFromExpo();
|
|
77
|
+
}
|
|
78
|
+
|
|
64
79
|
// Return safe fallback values
|
|
65
80
|
return this.getSafeDefaults();
|
|
66
81
|
} catch (error) {
|
|
67
|
-
|
|
82
|
+
// Use console.log here as well to be safe
|
|
83
|
+
console.error('[MagicPixel DeviceInfoHelper] Error getting device info:', error);
|
|
68
84
|
return this.getSafeDefaults();
|
|
69
85
|
}
|
|
70
86
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Platform","Logger","DeviceInfoHelper","initialize","initialized","expoApplication","require","expoDevice","expoConstants","default","logDbg","error","deviceInfo","logError","getAppInfo","getAppInfoFromExpo","getAppInfoFromDeviceInfo","getSafeDefaults","_Platform$Version","version","nativeApplicationVersion","buildNumber","nativeBuildVersion","packageName","applicationId","app_version","build_number","package_name","device_model_name","modelName","device_manufacturer","manufacturer","device_id","sessionId","os_name","OS","os_version","osVersion","Version","toString","is_tablet","deviceType","is_emulator","isDevice","uniqueId","bundleId","Promise","all","getVersion","getBuildNumber","getUniqueId","getBundleId","getModel","getManufacturerSync","getSystemVersion","isTablet","isEmulator","_Platform$Version2","getFormattedAppVersion","info","_defineProperty"],"sources":["device-info-helper.ts"],"sourcesContent":["import { Platform } from 'react-native';\nimport { Logger } from './logger';\n\ninterface DeviceAppInfo {\n app_version: string;\n build_number: string;\n package_name: string;\n device_model_name: string;\n device_manufacturer: string;\n device_id: string;\n os_name: string;\n os_version: string;\n is_tablet: boolean;\n is_emulator: boolean;\n}\n\n/**\n * Helper class to automatically detect device and app information\n * Supports both Expo and bare React Native:\n * 1. Tries Expo modules first (works in Expo Go)\n * 2. Falls back to react-native-device-info (for bare RN)\n * 3. Returns safe defaults if neither is available\n */\nexport class DeviceInfoHelper {\n private static expoApplication: any = null;\n private static expoDevice: any = null;\n private static expoConstants: any = null;\n private static deviceInfo: any = null;\n private static initialized = false;\n\n /**\n * Try to load Expo modules and react-native-device-info\n * This uses dynamic imports to avoid errors when modules aren't available\n */\n private static async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Try to load Expo modules first (works in Expo Go)\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.expoApplication = require('expo-application');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.expoDevice = require('expo-device');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.expoConstants = require('expo-constants').default;\n Logger.logDbg('Using Expo modules for device info');\n } catch (error) {\n Logger.logDbg(\n 'Expo modules not available, will try react-native-device-info'\n );\n }\n\n // Fall back to react-native-device-info (for bare RN)\n if (!this.expoApplication) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.deviceInfo = require('react-native-device-info').default;\n Logger.logDbg('Using react-native-device-info for device info');\n } catch (error) {\n Logger.logError(\n 'Neither Expo modules nor react-native-device-info available:',\n error\n );\n }\n }\n\n this.initialized = true;\n }\n\n /**\n * Get comprehensive app and device information\n * All methods are async-safe and handle errors gracefully\n */\n static async getAppInfo(): Promise<DeviceAppInfo> {\n await this.initialize();\n\n try {\n // Try Expo modules first\n if (this.expoApplication && this.expoDevice) {\n return await this.getAppInfoFromExpo();\n }\n\n // Fall back to react-native-device-info\n if (this.deviceInfo) {\n return await this.getAppInfoFromDeviceInfo();\n }\n\n // Return safe fallback values\n return this.getSafeDefaults();\n } catch (error) {\n Logger.logError('Error getting device info:', error);\n return this.getSafeDefaults();\n }\n }\n\n /**\n * Get device info using Expo modules (works in Expo Go)\n */\n private static async getAppInfoFromExpo(): Promise<DeviceAppInfo> {\n const version = this.expoApplication.nativeApplicationVersion || 'unknown';\n const buildNumber = this.expoApplication.nativeBuildVersion || 'unknown';\n const packageName = this.expoApplication.applicationId || 'unknown';\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: packageName,\n\n // Device information\n device_model_name: this.expoDevice.modelName || 'unknown',\n device_manufacturer: this.expoDevice.manufacturer || 'unknown',\n device_id: this.expoConstants.sessionId || 'unknown',\n\n // OS information\n os_name: Platform.OS,\n os_version:\n this.expoDevice.osVersion || Platform.Version?.toString() || 'unknown',\n\n // Additional useful info\n // DeviceType enum: UNKNOWN=0, PHONE=1, TABLET=2, DESKTOP=3, TV=4\n is_tablet: this.expoDevice.deviceType === 2, // DeviceType.TABLET = 2\n is_emulator: !this.expoDevice.isDevice,\n };\n }\n\n /**\n * Get device info using react-native-device-info (for bare RN)\n */\n private static async getAppInfoFromDeviceInfo(): Promise<DeviceAppInfo> {\n const [version, buildNumber, uniqueId, bundleId] = await Promise.all([\n this.deviceInfo.getVersion(),\n this.deviceInfo.getBuildNumber(),\n this.deviceInfo.getUniqueId(),\n this.deviceInfo.getBundleId(),\n ]);\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: bundleId,\n\n // Device information\n device_model_name: this.deviceInfo.getModel(),\n device_manufacturer: this.deviceInfo.getManufacturerSync(),\n device_id: uniqueId,\n\n // OS information\n os_name: Platform.OS,\n os_version: this.deviceInfo.getSystemVersion(),\n\n // Additional useful info\n is_tablet: this.deviceInfo.isTablet(),\n is_emulator: await this.deviceInfo.isEmulator(),\n };\n }\n\n /**\n * Safe default values when no device info library is available\n */\n private static getSafeDefaults(): DeviceAppInfo {\n return {\n app_version: 'unknown',\n build_number: 'unknown',\n package_name: 'unknown',\n device_model_name: 'unknown',\n device_manufacturer: 'unknown',\n device_id: 'unknown',\n os_name: Platform.OS,\n os_version: Platform.Version?.toString() || 'unknown',\n is_tablet: false,\n is_emulator: false,\n };\n }\n\n /**\n * Get app version in format: \"1.0.0 (123)\"\n * Combines version and build number for better tracking\n */\n static async getFormattedAppVersion(): Promise<string> {\n try {\n const info = await this.getAppInfo();\n return `${info.app_version} (${info.build_number})`;\n } catch (error) {\n Logger.logError('Error getting formatted app version:', error);\n return 'unknown';\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["Platform","Logger","DeviceInfoHelper","initialize","initialized","rnDeviceInfo","require","default","getVersion","deviceInfo","console","log","error","expoApp","expoDevice","expoConst","nativeApplicationVersion","expoApplication","expoConstants","getAppInfo","getAppInfoFromDeviceInfo","getAppInfoFromExpo","getSafeDefaults","_Platform$Version","version","buildNumber","nativeBuildVersion","packageName","applicationId","app_version","build_number","package_name","device_model_name","modelName","device_manufacturer","manufacturer","device_id","sessionId","os_name","OS","os_version","osVersion","Version","toString","is_tablet","deviceType","is_emulator","isDevice","uniqueId","bundleId","Promise","all","getBuildNumber","getUniqueId","getBundleId","getModel","getManufacturerSync","getSystemVersion","isTablet","isEmulator","_Platform$Version2","getFormattedAppVersion","info","logError","_defineProperty"],"sources":["device-info-helper.ts"],"sourcesContent":["import { Platform } from 'react-native';\nimport { Logger } from './logger';\n\ninterface DeviceAppInfo {\n app_version: string;\n build_number: string;\n package_name: string;\n device_model_name: string;\n device_manufacturer: string;\n device_id: string;\n os_name: string;\n os_version: string;\n is_tablet: boolean;\n is_emulator: boolean;\n}\n\n/**\n * Helper class to automatically detect device and app information\n * Supports both Expo and bare React Native:\n * 1. Tries react-native-device-info first (works in bare RN and Expo custom builds)\n * 2. Falls back to Expo modules (for Expo Go where native modules don't work)\n * 3. Returns safe defaults if neither is available\n */\nexport class DeviceInfoHelper {\n private static expoApplication: any = null;\n private static expoDevice: any = null;\n private static expoConstants: any = null;\n private static deviceInfo: any = null;\n private static initialized = false;\n\n /**\n * Try to load react-native-device-info first, then Expo modules\n * Uses console.log during init to avoid Logger dependency issues if module loading fails\n */\n private static async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // FIRST: Try react-native-device-info (preferred - works in bare RN and Expo custom builds)\n // This is a direct dependency of the SDK, so it should always be available except in Expo Go\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const rnDeviceInfo = require('react-native-device-info');\n // Validate the module is actually loaded and functional\n if (\n rnDeviceInfo &&\n typeof (rnDeviceInfo.default || rnDeviceInfo).getVersion === 'function'\n ) {\n this.deviceInfo = rnDeviceInfo.default || rnDeviceInfo;\n this.initialized = true;\n // Use console.log to avoid any Logger issues during early init\n console.log(\n '[MagicPixel DeviceInfoHelper] Using react-native-device-info'\n );\n return;\n }\n } catch (error) {\n // react-native-device-info not available (likely Expo Go)\n console.log(\n '[MagicPixel DeviceInfoHelper] react-native-device-info not available, trying Expo modules'\n );\n }\n\n // SECOND: Fall back to Expo modules (for Expo Go where native modules don't work)\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoApp = require('expo-application');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoDevice = require('expo-device');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoConst = require('expo-constants');\n\n // Validate modules are actually loaded (not undefined placeholders from Metro)\n if (\n expoApp &&\n expoDevice &&\n expoConst &&\n typeof expoApp.nativeApplicationVersion !== 'undefined'\n ) {\n this.expoApplication = expoApp;\n this.expoDevice = expoDevice;\n this.expoConstants = expoConst.default || expoConst;\n console.log('[MagicPixel DeviceInfoHelper] Using Expo modules');\n }\n } catch (error) {\n // Expo modules not available\n console.log(\n '[MagicPixel DeviceInfoHelper] Expo modules not available, using safe defaults'\n );\n }\n\n this.initialized = true;\n }\n\n /**\n * Get comprehensive app and device information\n * All methods are async-safe and handle errors gracefully\n */\n static async getAppInfo(): Promise<DeviceAppInfo> {\n await this.initialize();\n\n try {\n // Use react-native-device-info if available (preferred)\n if (this.deviceInfo) {\n return await this.getAppInfoFromDeviceInfo();\n }\n\n // Fall back to Expo modules (for Expo Go)\n if (this.expoApplication && this.expoDevice) {\n return await this.getAppInfoFromExpo();\n }\n\n // Return safe fallback values\n return this.getSafeDefaults();\n } catch (error) {\n // Use console.log here as well to be safe\n console.error('[MagicPixel DeviceInfoHelper] Error getting device info:', error);\n return this.getSafeDefaults();\n }\n }\n\n /**\n * Get device info using Expo modules (works in Expo Go)\n */\n private static async getAppInfoFromExpo(): Promise<DeviceAppInfo> {\n const version = this.expoApplication.nativeApplicationVersion || 'unknown';\n const buildNumber = this.expoApplication.nativeBuildVersion || 'unknown';\n const packageName = this.expoApplication.applicationId || 'unknown';\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: packageName,\n\n // Device information\n device_model_name: this.expoDevice.modelName || 'unknown',\n device_manufacturer: this.expoDevice.manufacturer || 'unknown',\n device_id: this.expoConstants.sessionId || 'unknown',\n\n // OS information\n os_name: Platform.OS,\n os_version:\n this.expoDevice.osVersion || Platform.Version?.toString() || 'unknown',\n\n // Additional useful info\n // DeviceType enum: UNKNOWN=0, PHONE=1, TABLET=2, DESKTOP=3, TV=4\n is_tablet: this.expoDevice.deviceType === 2, // DeviceType.TABLET = 2\n is_emulator: !this.expoDevice.isDevice,\n };\n }\n\n /**\n * Get device info using react-native-device-info (for bare RN)\n */\n private static async getAppInfoFromDeviceInfo(): Promise<DeviceAppInfo> {\n const [version, buildNumber, uniqueId, bundleId] = await Promise.all([\n this.deviceInfo.getVersion(),\n this.deviceInfo.getBuildNumber(),\n this.deviceInfo.getUniqueId(),\n this.deviceInfo.getBundleId(),\n ]);\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: bundleId,\n\n // Device information\n device_model_name: this.deviceInfo.getModel(),\n device_manufacturer: this.deviceInfo.getManufacturerSync(),\n device_id: uniqueId,\n\n // OS information\n os_name: Platform.OS,\n os_version: this.deviceInfo.getSystemVersion(),\n\n // Additional useful info\n is_tablet: this.deviceInfo.isTablet(),\n is_emulator: await this.deviceInfo.isEmulator(),\n };\n }\n\n /**\n * Safe default values when no device info library is available\n */\n private static getSafeDefaults(): DeviceAppInfo {\n return {\n app_version: 'unknown',\n build_number: 'unknown',\n package_name: 'unknown',\n device_model_name: 'unknown',\n device_manufacturer: 'unknown',\n device_id: 'unknown',\n os_name: Platform.OS,\n os_version: Platform.Version?.toString() || 'unknown',\n is_tablet: false,\n is_emulator: false,\n };\n }\n\n /**\n * Get app version in format: \"1.0.0 (123)\"\n * Combines version and build number for better tracking\n */\n static async getFormattedAppVersion(): Promise<string> {\n try {\n const info = await this.getAppInfo();\n return `${info.app_version} (${info.build_number})`;\n } catch (error) {\n Logger.logError('Error getting formatted app version:', error);\n return 'unknown';\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["sdk.d.ts"],"sourcesContent":["declare module '@magicpixel/rn-mp-client-sdk' {\n interface InitConfig {\n orgId: string;\n env: 'staging' | 'production';\n projectId: string;\n baseUrl: string;\n logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'none';\n eventDeduplicationWindowMs?: number;\n onInitFailure?: (error: Error) => void;\n }\n\n interface UserInfo {\n pid?: string;\n email?: string;\n phone?: string;\n country?: string;\n city?: string;\n state?: string;\n fName?: string;\n lName?: string;\n zip?: string;\n }\n\n interface PageLoadData {\n page_name: string;\n [key: string]: any;\n }\n\n class MagicPixelImpl {\n init(config: InitConfig): void;\n shutdown(): void;\n recordEvent(eventName: string, payload?: Record<string, any>): void;\n recordPageLoad(data: PageLoadData): void;\n setUserInfo(userInfo: UserInfo): void;\n setCustomerInfo(customerInfo: Record<string, any>): void;\n setDeviceInfo(customFields?: Record<string, any>): void;\n setDeepLinkUrl(url: string): void;\n setFirebaseAppInstanceId(id: string): void;\n getDebugId(): Promise<string | null>;\n setDataLayer(data: Record<string, any>): void;\n persistData(key: string, value: any): void;\n clearPersistedData(keys: string[]): void;\n getDataLayer(): Record<string, any>;\n getEventState(): Record<string, any>;\n hasEventHappened(eventName: string): boolean;\n registerEventProcessor(\n eventType: string,\n callback: (event: any) => void\n ): void;\n }\n\n export const MagicPixel: MagicPixelImpl;\n export const MagicPixelEventBus: any;\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -13,8 +13,8 @@ interface DeviceAppInfo {
|
|
|
13
13
|
/**
|
|
14
14
|
* Helper class to automatically detect device and app information
|
|
15
15
|
* Supports both Expo and bare React Native:
|
|
16
|
-
* 1. Tries
|
|
17
|
-
* 2. Falls back to
|
|
16
|
+
* 1. Tries react-native-device-info first (works in bare RN and Expo custom builds)
|
|
17
|
+
* 2. Falls back to Expo modules (for Expo Go where native modules don't work)
|
|
18
18
|
* 3. Returns safe defaults if neither is available
|
|
19
19
|
*/
|
|
20
20
|
export declare class DeviceInfoHelper {
|
|
@@ -24,8 +24,8 @@ export declare class DeviceInfoHelper {
|
|
|
24
24
|
private static deviceInfo;
|
|
25
25
|
private static initialized;
|
|
26
26
|
/**
|
|
27
|
-
* Try to load
|
|
28
|
-
*
|
|
27
|
+
* Try to load react-native-device-info first, then Expo modules
|
|
28
|
+
* Uses console.log during init to avoid Logger dependency issues if module loading fails
|
|
29
29
|
*/
|
|
30
30
|
private static initialize;
|
|
31
31
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magicpixel/rn-mp-client-sdk",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.23",
|
|
4
4
|
"description": "React Native SDK for MagicPixel analytics and tag management",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"src",
|
|
12
12
|
"lib",
|
|
13
|
+
"scripts",
|
|
13
14
|
"!lib/typescript/example",
|
|
14
15
|
"!**/__tests__",
|
|
15
16
|
"!**/__fixtures__",
|
|
@@ -20,6 +21,7 @@
|
|
|
20
21
|
"typescript": "tsc --noEmit",
|
|
21
22
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
22
23
|
"prepare": "bob build",
|
|
24
|
+
"postinstall": "node scripts/postinstall.js",
|
|
23
25
|
"release": "release-it",
|
|
24
26
|
"example": "yarn --cwd example",
|
|
25
27
|
"bootstrap": "yarn example && yarn && yarn example pods",
|
|
@@ -91,7 +93,13 @@
|
|
|
91
93
|
},
|
|
92
94
|
"peerDependencies": {
|
|
93
95
|
"react": "*",
|
|
94
|
-
"react-native": "*"
|
|
96
|
+
"react-native": "*",
|
|
97
|
+
"react-native-get-random-values": ">=1.8.0"
|
|
98
|
+
},
|
|
99
|
+
"peerDependenciesMeta": {
|
|
100
|
+
"react-native-get-random-values": {
|
|
101
|
+
"optional": true
|
|
102
|
+
}
|
|
95
103
|
},
|
|
96
104
|
"commitlint": {
|
|
97
105
|
"extends": [
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const os = require('os');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const child_process = require('child_process');
|
|
4
|
+
|
|
5
|
+
const root = path.resolve(__dirname, '..');
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
const options = {
|
|
8
|
+
cwd: process.cwd(),
|
|
9
|
+
env: process.env,
|
|
10
|
+
stdio: 'inherit',
|
|
11
|
+
encoding: 'utf-8',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
if (os.type() === 'Windows_NT') {
|
|
15
|
+
options.shell = true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let result;
|
|
19
|
+
|
|
20
|
+
if (process.cwd() !== root || args.length) {
|
|
21
|
+
// We're not in the root of the project, or additional arguments were passed
|
|
22
|
+
// In this case, forward the command to `yarn`
|
|
23
|
+
result = child_process.spawnSync('yarn', args, options);
|
|
24
|
+
} else {
|
|
25
|
+
// If `yarn` is run without arguments, perform bootstrap
|
|
26
|
+
result = child_process.spawnSync('yarn', ['bootstrap'], options);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
process.exitCode = result.status;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MagicPixel SDK Postinstall Script
|
|
5
|
+
* Detects bare React Native projects and displays setup instructions
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
// ANSI color codes
|
|
12
|
+
const colors = {
|
|
13
|
+
reset: '\x1b[0m',
|
|
14
|
+
bright: '\x1b[1m',
|
|
15
|
+
dim: '\x1b[2m',
|
|
16
|
+
yellow: '\x1b[33m',
|
|
17
|
+
cyan: '\x1b[36m',
|
|
18
|
+
white: '\x1b[37m',
|
|
19
|
+
bgMagenta: '\x1b[45m',
|
|
20
|
+
bgBlue: '\x1b[44m',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function getAppRoot() {
|
|
24
|
+
// Navigate up from node_modules/@magicpixel/rn-mp-client-sdk/scripts
|
|
25
|
+
// Structure: <app>/node_modules/@magicpixel/rn-mp-client-sdk/scripts/postinstall.js
|
|
26
|
+
// Or with yalc: <app>/.yalc/@magicpixel/rn-mp-client-sdk/scripts/postinstall.js
|
|
27
|
+
let current = __dirname;
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < 10; i++) {
|
|
30
|
+
current = path.dirname(current);
|
|
31
|
+
const packageJsonPath = path.join(current, 'package.json');
|
|
32
|
+
|
|
33
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
34
|
+
try {
|
|
35
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
36
|
+
// Skip our own package.json
|
|
37
|
+
if (pkg.name === '@magicpixel/rn-mp-client-sdk') {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
// Found the host app
|
|
41
|
+
return current;
|
|
42
|
+
} catch (e) {
|
|
43
|
+
// Continue searching
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function detectProjectType(appRoot) {
|
|
51
|
+
if (!appRoot) return 'unknown';
|
|
52
|
+
|
|
53
|
+
const hasIosFolder = fs.existsSync(path.join(appRoot, 'ios'));
|
|
54
|
+
const hasAndroidFolder = fs.existsSync(path.join(appRoot, 'android'));
|
|
55
|
+
const hasPodfile = fs.existsSync(path.join(appRoot, 'ios', 'Podfile'));
|
|
56
|
+
|
|
57
|
+
// Check for Expo
|
|
58
|
+
let hasExpo = false;
|
|
59
|
+
try {
|
|
60
|
+
const packageJsonPath = path.join(appRoot, 'package.json');
|
|
61
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
62
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
63
|
+
hasExpo = !!(
|
|
64
|
+
pkg.dependencies?.expo ||
|
|
65
|
+
pkg.devDependencies?.expo ||
|
|
66
|
+
pkg.dependencies?.['expo-modules-core']
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
} catch (e) {
|
|
70
|
+
// Ignore errors
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (hasExpo && !hasIosFolder && !hasAndroidFolder) {
|
|
74
|
+
return 'expo-managed';
|
|
75
|
+
}
|
|
76
|
+
if (hasExpo && (hasIosFolder || hasAndroidFolder)) {
|
|
77
|
+
return 'expo-bare';
|
|
78
|
+
}
|
|
79
|
+
if (!hasExpo && (hasIosFolder || hasAndroidFolder)) {
|
|
80
|
+
return 'bare-rn';
|
|
81
|
+
}
|
|
82
|
+
return 'unknown';
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function printBareRNMessage() {
|
|
86
|
+
const c = colors;
|
|
87
|
+
// Use stderr for better visibility (npm sometimes hides stdout from postinstall)
|
|
88
|
+
const log = (msg) => process.stderr.write(msg + '\n');
|
|
89
|
+
|
|
90
|
+
log('');
|
|
91
|
+
log(`${c.bgMagenta}${c.white}${c.bright} ${c.reset}`);
|
|
92
|
+
log(`${c.bgMagenta}${c.white}${c.bright} ╔═══════════════════════════════════════════════════════════════╗ ${c.reset}`);
|
|
93
|
+
log(`${c.bgMagenta}${c.white}${c.bright} ║ ║ ${c.reset}`);
|
|
94
|
+
log(`${c.bgMagenta}${c.white}${c.bright} ║ 🔮 MAGICPIXEL SDK - BARE REACT NATIVE SETUP REQUIRED 🔮 ║ ${c.reset}`);
|
|
95
|
+
log(`${c.bgMagenta}${c.white}${c.bright} ║ ║ ${c.reset}`);
|
|
96
|
+
log(`${c.bgMagenta}${c.white}${c.bright} ╚═══════════════════════════════════════════════════════════════╝ ${c.reset}`);
|
|
97
|
+
log(`${c.bgMagenta}${c.white}${c.bright} ${c.reset}`);
|
|
98
|
+
log('');
|
|
99
|
+
log(`${c.cyan}${c.bright} Complete these steps to finish SDK installation:${c.reset}`);
|
|
100
|
+
log('');
|
|
101
|
+
log(`${c.yellow}${c.bright} STEP 1:${c.reset} Link native modules (iOS)`);
|
|
102
|
+
log(`${c.dim} ─────────────────────────────────────${c.reset}`);
|
|
103
|
+
log(` ${c.white}cd ios && pod install && cd ..${c.reset}`);
|
|
104
|
+
log('');
|
|
105
|
+
log(`${c.yellow}${c.bright} STEP 2:${c.reset} Add polyfill to index.js ${c.dim}(MUST be first import!)${c.reset}`);
|
|
106
|
+
log(`${c.dim} ─────────────────────────────────────${c.reset}`);
|
|
107
|
+
log(` ${c.white}import 'react-native-get-random-values';${c.reset}`);
|
|
108
|
+
log('');
|
|
109
|
+
log(`${c.yellow}${c.bright} STEP 3:${c.reset} Rebuild your app ${c.dim}(required after pod install)${c.reset}`);
|
|
110
|
+
log(`${c.dim} ─────────────────────────────────────${c.reset}`);
|
|
111
|
+
log(` ${c.white}• Kill the app in simulator/device${c.reset}`);
|
|
112
|
+
log(` ${c.white}• Stop Metro (Ctrl+C)${c.reset}`);
|
|
113
|
+
log(` ${c.white}• Run: npx react-native run-ios${c.reset}`);
|
|
114
|
+
log('');
|
|
115
|
+
log(`${c.dim} ⚠️ Without these steps, you'll see:${c.reset}`);
|
|
116
|
+
log(`${c.dim} TurboModuleRegistry.getEnforcing(...): 'RNGetRandomValues' not found${c.reset}`);
|
|
117
|
+
log('');
|
|
118
|
+
log(`${c.dim} 📖 Full docs: https://github.com/digital-madtech/mp-rn-client-sdk#readme${c.reset}`);
|
|
119
|
+
log('');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function main() {
|
|
123
|
+
try {
|
|
124
|
+
const appRoot = getAppRoot();
|
|
125
|
+
const projectType = detectProjectType(appRoot);
|
|
126
|
+
|
|
127
|
+
if (projectType === 'bare-rn' || projectType === 'expo-bare') {
|
|
128
|
+
printBareRNMessage();
|
|
129
|
+
}
|
|
130
|
+
// For expo-managed, no message needed - it handles native modules automatically
|
|
131
|
+
} catch (error) {
|
|
132
|
+
// Silently fail - don't break npm install
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
main();
|
|
@@ -17,8 +17,8 @@ interface DeviceAppInfo {
|
|
|
17
17
|
/**
|
|
18
18
|
* Helper class to automatically detect device and app information
|
|
19
19
|
* Supports both Expo and bare React Native:
|
|
20
|
-
* 1. Tries
|
|
21
|
-
* 2. Falls back to
|
|
20
|
+
* 1. Tries react-native-device-info first (works in bare RN and Expo custom builds)
|
|
21
|
+
* 2. Falls back to Expo modules (for Expo Go where native modules don't work)
|
|
22
22
|
* 3. Returns safe defaults if neither is available
|
|
23
23
|
*/
|
|
24
24
|
export class DeviceInfoHelper {
|
|
@@ -29,39 +29,63 @@ export class DeviceInfoHelper {
|
|
|
29
29
|
private static initialized = false;
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* Try to load
|
|
33
|
-
*
|
|
32
|
+
* Try to load react-native-device-info first, then Expo modules
|
|
33
|
+
* Uses console.log during init to avoid Logger dependency issues if module loading fails
|
|
34
34
|
*/
|
|
35
35
|
private static async initialize(): Promise<void> {
|
|
36
36
|
if (this.initialized) return;
|
|
37
37
|
|
|
38
|
-
// Try
|
|
38
|
+
// FIRST: Try react-native-device-info (preferred - works in bare RN and Expo custom builds)
|
|
39
|
+
// This is a direct dependency of the SDK, so it should always be available except in Expo Go
|
|
39
40
|
try {
|
|
40
41
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
41
|
-
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
const rnDeviceInfo = require('react-native-device-info');
|
|
43
|
+
// Validate the module is actually loaded and functional
|
|
44
|
+
if (
|
|
45
|
+
rnDeviceInfo &&
|
|
46
|
+
typeof (rnDeviceInfo.default || rnDeviceInfo).getVersion === 'function'
|
|
47
|
+
) {
|
|
48
|
+
this.deviceInfo = rnDeviceInfo.default || rnDeviceInfo;
|
|
49
|
+
this.initialized = true;
|
|
50
|
+
// Use console.log to avoid any Logger issues during early init
|
|
51
|
+
console.log(
|
|
52
|
+
'[MagicPixel DeviceInfoHelper] Using react-native-device-info'
|
|
53
|
+
);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
47
56
|
} catch (error) {
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
// react-native-device-info not available (likely Expo Go)
|
|
58
|
+
console.log(
|
|
59
|
+
'[MagicPixel DeviceInfoHelper] react-native-device-info not available, trying Expo modules'
|
|
50
60
|
);
|
|
51
61
|
}
|
|
52
62
|
|
|
53
|
-
// Fall back to
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
// SECOND: Fall back to Expo modules (for Expo Go where native modules don't work)
|
|
64
|
+
try {
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
66
|
+
const expoApp = require('expo-application');
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
68
|
+
const expoDevice = require('expo-device');
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
70
|
+
const expoConst = require('expo-constants');
|
|
71
|
+
|
|
72
|
+
// Validate modules are actually loaded (not undefined placeholders from Metro)
|
|
73
|
+
if (
|
|
74
|
+
expoApp &&
|
|
75
|
+
expoDevice &&
|
|
76
|
+
expoConst &&
|
|
77
|
+
typeof expoApp.nativeApplicationVersion !== 'undefined'
|
|
78
|
+
) {
|
|
79
|
+
this.expoApplication = expoApp;
|
|
80
|
+
this.expoDevice = expoDevice;
|
|
81
|
+
this.expoConstants = expoConst.default || expoConst;
|
|
82
|
+
console.log('[MagicPixel DeviceInfoHelper] Using Expo modules');
|
|
64
83
|
}
|
|
84
|
+
} catch (error) {
|
|
85
|
+
// Expo modules not available
|
|
86
|
+
console.log(
|
|
87
|
+
'[MagicPixel DeviceInfoHelper] Expo modules not available, using safe defaults'
|
|
88
|
+
);
|
|
65
89
|
}
|
|
66
90
|
|
|
67
91
|
this.initialized = true;
|
|
@@ -75,20 +99,21 @@ export class DeviceInfoHelper {
|
|
|
75
99
|
await this.initialize();
|
|
76
100
|
|
|
77
101
|
try {
|
|
78
|
-
//
|
|
79
|
-
if (this.expoApplication && this.expoDevice) {
|
|
80
|
-
return await this.getAppInfoFromExpo();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Fall back to react-native-device-info
|
|
102
|
+
// Use react-native-device-info if available (preferred)
|
|
84
103
|
if (this.deviceInfo) {
|
|
85
104
|
return await this.getAppInfoFromDeviceInfo();
|
|
86
105
|
}
|
|
87
106
|
|
|
107
|
+
// Fall back to Expo modules (for Expo Go)
|
|
108
|
+
if (this.expoApplication && this.expoDevice) {
|
|
109
|
+
return await this.getAppInfoFromExpo();
|
|
110
|
+
}
|
|
111
|
+
|
|
88
112
|
// Return safe fallback values
|
|
89
113
|
return this.getSafeDefaults();
|
|
90
114
|
} catch (error) {
|
|
91
|
-
|
|
115
|
+
// Use console.log here as well to be safe
|
|
116
|
+
console.error('[MagicPixel DeviceInfoHelper] Error getting device info:', error);
|
|
92
117
|
return this.getSafeDefaults();
|
|
93
118
|
}
|
|
94
119
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
declare module '@magicpixel/rn-mp-client-sdk' {
|
|
2
|
+
interface InitConfig {
|
|
3
|
+
orgId: string;
|
|
4
|
+
env: 'staging' | 'production';
|
|
5
|
+
projectId: string;
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'none';
|
|
8
|
+
eventDeduplicationWindowMs?: number;
|
|
9
|
+
onInitFailure?: (error: Error) => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface UserInfo {
|
|
13
|
+
pid?: string;
|
|
14
|
+
email?: string;
|
|
15
|
+
phone?: string;
|
|
16
|
+
country?: string;
|
|
17
|
+
city?: string;
|
|
18
|
+
state?: string;
|
|
19
|
+
fName?: string;
|
|
20
|
+
lName?: string;
|
|
21
|
+
zip?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface PageLoadData {
|
|
25
|
+
page_name: string;
|
|
26
|
+
[key: string]: any;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class MagicPixelImpl {
|
|
30
|
+
init(config: InitConfig): void;
|
|
31
|
+
shutdown(): void;
|
|
32
|
+
recordEvent(eventName: string, payload?: Record<string, any>): void;
|
|
33
|
+
recordPageLoad(data: PageLoadData): void;
|
|
34
|
+
setUserInfo(userInfo: UserInfo): void;
|
|
35
|
+
setCustomerInfo(customerInfo: Record<string, any>): void;
|
|
36
|
+
setDeviceInfo(customFields?: Record<string, any>): void;
|
|
37
|
+
setDeepLinkUrl(url: string): void;
|
|
38
|
+
setFirebaseAppInstanceId(id: string): void;
|
|
39
|
+
getDebugId(): Promise<string | null>;
|
|
40
|
+
setDataLayer(data: Record<string, any>): void;
|
|
41
|
+
persistData(key: string, value: any): void;
|
|
42
|
+
clearPersistedData(keys: string[]): void;
|
|
43
|
+
getDataLayer(): Record<string, any>;
|
|
44
|
+
getEventState(): Record<string, any>;
|
|
45
|
+
hasEventHappened(eventName: string): boolean;
|
|
46
|
+
registerEventProcessor(
|
|
47
|
+
eventType: string,
|
|
48
|
+
callback: (event: any) => void
|
|
49
|
+
): void;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const MagicPixel: MagicPixelImpl;
|
|
53
|
+
export const MagicPixelEventBus: any;
|
|
54
|
+
}
|