@advenue/react-native 0.6.6 → 0.7.0

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/dist/index.cjs CHANGED
@@ -221,7 +221,7 @@ function sha256Hex(message) {
221
221
  // package.json
222
222
  var package_default = {
223
223
  name: "@advenue/react-native",
224
- version: "0.6.6",
224
+ version: "0.7.0",
225
225
  description: "Advenue MMP React Native SDK \u2014 attribution, install tracking, and deep links (bundled iOS/Android Expo native modules)",
226
226
  type: "module",
227
227
  license: "MIT",
@@ -357,6 +357,19 @@ function getPlatformOS() {
357
357
  return null;
358
358
  }
359
359
  }
360
+ function getOsVersion() {
361
+ try {
362
+ const rn = (0, import_native_require.requireReactNative)();
363
+ if (!rn) return null;
364
+ if (rn.Platform.OS === "android") {
365
+ const release = rn.Platform.constants?.Release;
366
+ return release != null ? String(release) : null;
367
+ }
368
+ return rn.Platform.Version != null ? String(rn.Platform.Version) : null;
369
+ } catch {
370
+ return null;
371
+ }
372
+ }
360
373
  function getAppState() {
361
374
  try {
362
375
  const rn = (0, import_native_require.requireReactNative)();
@@ -530,7 +543,14 @@ var Advenue = {
530
543
  installFlagStore = storage;
531
544
  secureStore = secureMod ? createSecureStore(secureMod) : createNativeSecureStore(iosMod);
532
545
  const deviceId = rest.deviceId ?? await (0, import_sdk_core.resolveDurableDeviceId)(storage, secureStore ?? void 0);
533
- instance = new import_sdk_core.AdvenueClient({ ...rest, platform, deviceId, storage });
546
+ const osVersion = rest.osVersion ?? getOsVersion() ?? void 0;
547
+ instance = new import_sdk_core.AdvenueClient({
548
+ ...rest,
549
+ platform,
550
+ deviceId,
551
+ storage,
552
+ ...osVersion ? { osVersion } : {}
553
+ });
534
554
  instance.debugLog(`SDK v${package_default.version} \u2014 events -> ${configuredEndpoint}`);
535
555
  void resolveAdvertisingId().catch((err) => reportError("enrich.advertisingId", err));
536
556
  const deviceInfo = collectDeviceInfo({
package/dist/index.js CHANGED
@@ -217,7 +217,7 @@ function sha256Hex(message) {
217
217
  // package.json
218
218
  var package_default = {
219
219
  name: "@advenue/react-native",
220
- version: "0.6.6",
220
+ version: "0.7.0",
221
221
  description: "Advenue MMP React Native SDK \u2014 attribution, install tracking, and deep links (bundled iOS/Android Expo native modules)",
222
222
  type: "module",
223
223
  license: "MIT",
@@ -353,6 +353,19 @@ function getPlatformOS() {
353
353
  return null;
354
354
  }
355
355
  }
356
+ function getOsVersion() {
357
+ try {
358
+ const rn = (0, import_native_require.requireReactNative)();
359
+ if (!rn) return null;
360
+ if (rn.Platform.OS === "android") {
361
+ const release = rn.Platform.constants?.Release;
362
+ return release != null ? String(release) : null;
363
+ }
364
+ return rn.Platform.Version != null ? String(rn.Platform.Version) : null;
365
+ } catch {
366
+ return null;
367
+ }
368
+ }
356
369
  function getAppState() {
357
370
  try {
358
371
  const rn = (0, import_native_require.requireReactNative)();
@@ -526,7 +539,14 @@ var Advenue = {
526
539
  installFlagStore = storage;
527
540
  secureStore = secureMod ? createSecureStore(secureMod) : createNativeSecureStore(iosMod);
528
541
  const deviceId = rest.deviceId ?? await resolveDurableDeviceId(storage, secureStore ?? void 0);
529
- instance = new AdvenueClient({ ...rest, platform, deviceId, storage });
542
+ const osVersion = rest.osVersion ?? getOsVersion() ?? void 0;
543
+ instance = new AdvenueClient({
544
+ ...rest,
545
+ platform,
546
+ deviceId,
547
+ storage,
548
+ ...osVersion ? { osVersion } : {}
549
+ });
530
550
  instance.debugLog(`SDK v${package_default.version} \u2014 events -> ${configuredEndpoint}`);
531
551
  void resolveAdvertisingId().catch((err) => reportError("enrich.advertisingId", err));
532
552
  const deviceInfo = collectDeviceInfo({
@@ -17,4 +17,8 @@ Pod::Spec.new do |s|
17
17
  s.dependency 'ExpoModulesCore'
18
18
 
19
19
  s.source_files = '**/*.{h,m,swift}'
20
+ # Apple privacy manifest (required since May 2024 for SDKs that persist
21
+ # state / collect device info) — shipped as a resource bundle so Xcode
22
+ # aggregates it into the app's privacy report.
23
+ s.resource_bundles = { 'AdvenueIos_Privacy' => ['PrivacyInfo.xcprivacy'] }
20
24
  end
@@ -0,0 +1,56 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <!-- The SDK itself does not track (no fingerprinting; IDFA collection is
6
+ app-mediated via the ATT prompt) and calls no tracking domains. -->
7
+ <key>NSPrivacyTracking</key>
8
+ <false/>
9
+ <key>NSPrivacyTrackingDomains</key>
10
+ <array/>
11
+ <key>NSPrivacyCollectedDataTypes</key>
12
+ <array>
13
+ <!-- Durable SDK device id (Keychain-backed) — attribution/analytics. -->
14
+ <dict>
15
+ <key>NSPrivacyCollectedDataType</key>
16
+ <string>NSPrivacyCollectedDataTypeDeviceID</string>
17
+ <key>NSPrivacyCollectedDataTypeLinked</key>
18
+ <true/>
19
+ <key>NSPrivacyCollectedDataTypeTracking</key>
20
+ <false/>
21
+ <key>NSPrivacyCollectedDataTypePurposes</key>
22
+ <array>
23
+ <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
24
+ <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
25
+ </array>
26
+ </dict>
27
+ <!-- Coarse device characteristics (model, OS version, locale, screen) —
28
+ event enrichment / attribution corroboration. -->
29
+ <dict>
30
+ <key>NSPrivacyCollectedDataType</key>
31
+ <string>NSPrivacyCollectedDataTypeOtherDataTypes</string>
32
+ <key>NSPrivacyCollectedDataTypeLinked</key>
33
+ <true/>
34
+ <key>NSPrivacyCollectedDataTypeTracking</key>
35
+ <false/>
36
+ <key>NSPrivacyCollectedDataTypePurposes</key>
37
+ <array>
38
+ <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
39
+ </array>
40
+ </dict>
41
+ </array>
42
+ <key>NSPrivacyAccessedAPITypes</key>
43
+ <array>
44
+ <!-- CA92.1: UserDefaults is read/written only for this app's own SDK
45
+ state (device id mirror, install flag, consent). -->
46
+ <dict>
47
+ <key>NSPrivacyAccessedAPIType</key>
48
+ <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
49
+ <key>NSPrivacyAccessedAPITypeReasons</key>
50
+ <array>
51
+ <string>CA92.1</string>
52
+ </array>
53
+ </dict>
54
+ </array>
55
+ </dict>
56
+ </plist>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@advenue/react-native",
3
- "version": "0.6.6",
3
+ "version": "0.7.0",
4
4
  "description": "Advenue MMP React Native SDK — attribution, install tracking, and deep links (bundled iOS/Android Expo native modules)",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
@@ -27,6 +27,7 @@ import {
27
27
  getAppState,
28
28
  getIosNative,
29
29
  getLinking,
30
+ getOsVersion,
30
31
  getPlatformOS,
31
32
  } from './native';
32
33
  import { createNativeSecureStore, createNativeStorage } from './native-storage';
@@ -339,7 +340,16 @@ export const Advenue = {
339
340
  secureStore = secureMod ? createSecureStore(secureMod) : createNativeSecureStore(iosMod);
340
341
  const deviceId =
341
342
  rest.deviceId ?? (await resolveDurableDeviceId(storage, secureStore ?? undefined));
342
- instance = new AdvenueClient({ ...rest, platform, deviceId, storage });
343
+ // Auto-collect the OS release version — it feeds the server's normalized
344
+ // probabilistic fingerprint (spec D1); an explicit config value wins.
345
+ const osVersion = rest.osVersion ?? getOsVersion() ?? undefined;
346
+ instance = new AdvenueClient({
347
+ ...rest,
348
+ platform,
349
+ deviceId,
350
+ storage,
351
+ ...(osVersion ? { osVersion } : {}),
352
+ });
343
353
  // One-line ground truth for "which SDK build talks to which host" — the
344
354
  // exact questions a silent integration always raises first.
345
355
  instance.debugLog(`SDK v${pkg.version} — events -> ${configuredEndpoint}`);
package/src/native.ts CHANGED
@@ -44,6 +44,29 @@ export function getPlatformOS(): string | null {
44
44
  }
45
45
  }
46
46
 
47
+ /**
48
+ * OS *release* version for attribution matching: iOS `Platform.Version` is the
49
+ * system version string ('18.2'); Android `Platform.Version` is the API LEVEL
50
+ * (34) — sending it would break the server's normalized fingerprint (the
51
+ * click-side browser UA says "Android 14"), so Android reads
52
+ * `Platform.constants.Release` and degrades to null when it's absent.
53
+ */
54
+ export function getOsVersion(): string | null {
55
+ try {
56
+ const rn = requireReactNative() as {
57
+ Platform: { OS: string; Version?: unknown; constants?: { Release?: unknown } };
58
+ } | null;
59
+ if (!rn) return null;
60
+ if (rn.Platform.OS === 'android') {
61
+ const release = rn.Platform.constants?.Release;
62
+ return release != null ? String(release) : null;
63
+ }
64
+ return rn.Platform.Version != null ? String(rn.Platform.Version) : null;
65
+ } catch {
66
+ return null;
67
+ }
68
+ }
69
+
47
70
  /** Subscription handle returned by AppState.addEventListener. */
48
71
  export interface AppStateSubscription {
49
72
  remove(): void;