@kontextso/sdk-react-native 3.3.1-rc.0 → 3.4.0-rc.1

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,117 @@
1
+ import { Platform } from 'react-native'
2
+ import NativeRNKontext from '../NativeRNKontext'
3
+
4
+ const ZERO_UUID = '00000000-0000-0000-0000-000000000000'
5
+
6
+ // Mirrors TrackingStatus enum from Flutter / ATTrackingManager raw values
7
+ export enum TrackingStatus {
8
+ NotDetermined = 0,
9
+ Restricted = 1,
10
+ Denied = 2,
11
+ Authorized = 3,
12
+ NotSupported = 4, // iOS < 14 or non-iOS
13
+ }
14
+
15
+ let didRunStartupFlow = false
16
+ let startupFlowPromise: Promise<void> | null = null
17
+
18
+ /**
19
+ * Requests ATT authorization on iOS >= 14.5.
20
+ * On iOS 14.0–14.4 we intentionally skip the request: the dialog is not
21
+ * required to read IDFA on those versions, and asking only to get denied
22
+ * would permanently revoke access.
23
+ * Guaranteed to run only once per app session regardless of call count.
24
+ */
25
+ export function requestTrackingAuthorization(): Promise<void> {
26
+ if (didRunStartupFlow) {
27
+ return startupFlowPromise ?? Promise.resolve()
28
+ }
29
+ didRunStartupFlow = true
30
+ startupFlowPromise = _runStartupFlow()
31
+ return startupFlowPromise
32
+ }
33
+
34
+ export async function getTrackingAuthorizationStatus(): Promise<TrackingStatus> {
35
+ if (Platform.OS !== 'ios') {
36
+ return TrackingStatus.NotSupported
37
+ }
38
+ try {
39
+ const raw = await NativeRNKontext.getTrackingAuthorizationStatus()
40
+ return _mapRawStatus(raw)
41
+ } catch (error) {
42
+ console.error(error)
43
+ return TrackingStatus.NotSupported
44
+ }
45
+ }
46
+
47
+ export async function getAdvertisingId(): Promise<string | null> {
48
+ try {
49
+ const id = await NativeRNKontext.getAdvertisingId()
50
+ return _normalizeId(id)
51
+ } catch (error) {
52
+ console.error(error)
53
+ return null
54
+ }
55
+ }
56
+
57
+ export async function getVendorId(): Promise<string | null> {
58
+ if (Platform.OS !== 'ios') {
59
+ return null
60
+ }
61
+ try {
62
+ const id = await NativeRNKontext.getVendorId()
63
+ return _normalizeId(id)
64
+ } catch (error) {
65
+ console.error(error)
66
+ return null
67
+ }
68
+ }
69
+
70
+ export async function resolveIds(fallbacks?: {
71
+ vendorId?: string | undefined
72
+ advertisingId?: string | undefined
73
+ }): Promise<{ vendorId: string | null; advertisingId: string | null }> {
74
+ const [vendorId, advertisingId] = await Promise.all([getVendorId(), getAdvertisingId()])
75
+
76
+ return {
77
+ vendorId: vendorId ?? _normalizeId(fallbacks?.vendorId),
78
+ advertisingId: advertisingId ?? _normalizeId(fallbacks?.advertisingId),
79
+ }
80
+ }
81
+
82
+ // ─── internal ────────────────────────────────────────────────────────────────
83
+
84
+ async function _runStartupFlow(): Promise<void> {
85
+ if (Platform.OS !== 'ios') return
86
+
87
+ try {
88
+ if (!_isVersionAtLeast145(Platform.Version)) return
89
+
90
+ const status = await getTrackingAuthorizationStatus()
91
+ if (status !== TrackingStatus.NotDetermined) return
92
+
93
+ await NativeRNKontext.requestTrackingAuthorization()
94
+ } catch (error) {
95
+ console.error(error)
96
+ }
97
+ }
98
+
99
+ /**
100
+ * iOS 14.0–14.4: ATT dialog not required for IDFA access.
101
+ * Requesting it risks permanent denial, so we only request on >= 14.5.
102
+ */
103
+ function _isVersionAtLeast145(version: string): boolean {
104
+ const [major = 0, minor = 0] = version.split('.').map(Number)
105
+ return major > 14 || (major === 14 && minor >= 5)
106
+ }
107
+
108
+ function _mapRawStatus(raw: number): TrackingStatus {
109
+ if (raw >= 0 && raw <= 4) return raw as TrackingStatus
110
+ return TrackingStatus.NotSupported
111
+ }
112
+
113
+ function _normalizeId(id: string | null | undefined): string | null {
114
+ if (!id || id.trim() === '') return null
115
+ if (id.toLowerCase() === ZERO_UUID) return null
116
+ return id
117
+ }
@@ -0,0 +1,75 @@
1
+ import { Platform } from 'react-native'
2
+ import NativeRNKontext from '../NativeRNKontext'
3
+
4
+ export interface SkAdNetworkFidelity {
5
+ fidelity: number
6
+ signature: string
7
+ nonce: string
8
+ timestamp: string | number
9
+ }
10
+
11
+ export interface SkAdNetworkImpressionParams {
12
+ // Required
13
+ version: string
14
+ network: string
15
+ itunesItem: string | number
16
+ sourceApp: string | number
17
+ // Optional
18
+ sourceIdentifier?: string | number
19
+ campaign?: string | number
20
+ fidelities?: SkAdNetworkFidelity[]
21
+ nonce?: string
22
+ timestamp?: string | number
23
+ signature?: string
24
+ }
25
+
26
+ let impressionReady = false
27
+
28
+ export async function initSkAdNetworkImpression(params: SkAdNetworkImpressionParams): Promise<boolean> {
29
+ if (Platform.OS !== 'ios') return false
30
+
31
+ try {
32
+ const result = await NativeRNKontext.initSkAdNetworkImpression(params)
33
+ impressionReady = result
34
+ return result
35
+ } catch (e) {
36
+ impressionReady = false
37
+ console.error('[SKAdNetwork] Error initializing impression:', e)
38
+ return false
39
+ }
40
+ }
41
+
42
+ export async function startSkAdNetworkImpression(): Promise<boolean> {
43
+ if (Platform.OS !== 'ios' || !impressionReady) return false
44
+
45
+ try {
46
+ return await NativeRNKontext.startSkAdNetworkImpression()
47
+ } catch (e) {
48
+ console.error('[SKAdNetwork] Error starting impression:', e)
49
+ return false
50
+ }
51
+ }
52
+
53
+ export async function endSkAdNetworkImpression(): Promise<boolean> {
54
+ if (Platform.OS !== 'ios' || !impressionReady) return false
55
+
56
+ try {
57
+ return await NativeRNKontext.endSkAdNetworkImpression()
58
+ } catch (e) {
59
+ console.error('[SKAdNetwork] Error ending impression:', e)
60
+ return false
61
+ }
62
+ }
63
+
64
+ export async function disposeSkAdNetwork(): Promise<boolean> {
65
+ impressionReady = false
66
+
67
+ if (Platform.OS !== 'ios') return false
68
+
69
+ try {
70
+ return await NativeRNKontext.disposeSkAdNetwork()
71
+ } catch (e) {
72
+ console.error('[SKAdNetwork] Error disposing:', e)
73
+ return false
74
+ }
75
+ }