@advenue/react-native 0.8.0 → 1.0.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/README.md +8 -7
- package/android/src/main/java/expo/modules/advenue/AdvenueAndroidModule.kt +118 -347
- package/android/src/main/kotlin/io/advenue/Advenue.kt +549 -0
- package/android/src/main/kotlin/io/advenue/AdvenueConfig.kt +114 -0
- package/android/src/main/kotlin/io/advenue/core/Backoff.kt +28 -0
- package/android/src/main/kotlin/io/advenue/core/ClientEvent.kt +136 -0
- package/android/src/main/kotlin/io/advenue/core/CommandPipe.kt +186 -0
- package/android/src/main/kotlin/io/advenue/core/Consent.kt +52 -0
- package/android/src/main/kotlin/io/advenue/core/Contracts.kt +80 -0
- package/android/src/main/kotlin/io/advenue/core/Conversion.kt +69 -0
- package/android/src/main/kotlin/io/advenue/core/Engine.kt +414 -0
- package/android/src/main/kotlin/io/advenue/core/EventQueue.kt +89 -0
- package/android/src/main/kotlin/io/advenue/core/HmacSigner.kt +31 -0
- package/android/src/main/kotlin/io/advenue/core/InstallReferrer.kt +146 -0
- package/android/src/main/kotlin/io/advenue/core/Json.kt +272 -0
- package/android/src/main/kotlin/io/advenue/core/Limits.kt +47 -0
- package/android/src/main/kotlin/io/advenue/core/MetaReferrer.kt +80 -0
- package/android/src/main/kotlin/io/advenue/core/SessionTracker.kt +189 -0
- package/android/src/main/kotlin/io/advenue/core/SystemServices.kt +58 -0
- package/android/src/main/kotlin/io/advenue/core/Tcf.kt +48 -0
- package/android/src/main/kotlin/io/advenue/core/Time.kt +56 -0
- package/android/src/main/kotlin/io/advenue/platform/Collectors.kt +149 -0
- package/android/src/main/kotlin/io/advenue/platform/CompositeStore.kt +33 -0
- package/android/src/main/kotlin/io/advenue/platform/ConversionFetcher.kt +68 -0
- package/android/src/main/kotlin/io/advenue/platform/ForegroundTracker.kt +90 -0
- package/android/src/main/kotlin/io/advenue/platform/HttpUrlTransport.kt +101 -0
- package/android/src/main/kotlin/io/advenue/platform/Identity.kt +79 -0
- package/android/src/main/kotlin/io/advenue/platform/InstallEnrichment.kt +197 -0
- package/android/src/main/kotlin/io/advenue/platform/InstallScopedStore.kt +91 -0
- package/android/src/main/kotlin/io/advenue/platform/LifecycleBridge.kt +72 -0
- package/android/src/main/kotlin/io/advenue/platform/PreferencesStore.kt +32 -0
- package/android/src/main/kotlin/io/advenue/plugin/Contracts.kt +67 -0
- package/android/src/main/kotlin/io/advenue/plugin/FirebaseAppInstanceIdSource.kt +73 -0
- package/android/src/main/kotlin/io/advenue/plugin/PlayAdvertisingIdSource.kt +47 -0
- package/android/src/main/kotlin/io/advenue/plugin/PlayInstallReferrerSource.kt +85 -0
- package/android/src/main/kotlin/io/advenue/plugin/PlayIntegritySource.kt +86 -0
- package/android/src/main/kotlin/io/advenue/plugin/PluginRegistry.kt +61 -0
- package/dist/index.cjs +183 -655
- package/dist/index.d.cts +199 -331
- package/dist/index.d.ts +199 -331
- package/dist/index.js +182 -661
- package/ios/AdvenueIosModule.swift +144 -432
- package/ios/vendor/Advenue/Advenue.swift +596 -0
- package/ios/vendor/Advenue/AdvenueConfig.swift +77 -0
- package/ios/vendor/AdvenueCore/AdvenueValue.swift +103 -0
- package/ios/vendor/AdvenueCore/Attestation.swift +52 -0
- package/ios/vendor/AdvenueCore/Backoff.swift +28 -0
- package/ios/vendor/AdvenueCore/ClientEvent.swift +154 -0
- package/ios/vendor/AdvenueCore/Consent.swift +40 -0
- package/ios/vendor/AdvenueCore/Contracts.swift +59 -0
- package/ios/vendor/AdvenueCore/Conversion.swift +74 -0
- package/ios/vendor/AdvenueCore/ConversionValue.swift +217 -0
- package/ios/vendor/AdvenueCore/Engine.swift +587 -0
- package/ios/vendor/AdvenueCore/EventQueue.swift +89 -0
- package/ios/vendor/AdvenueCore/Limits.swift +41 -0
- package/ios/vendor/AdvenueCore/PIIScrub.swift +102 -0
- package/ios/vendor/AdvenueCore/SessionTracker.swift +139 -0
- package/ios/vendor/AdvenueCore/SkanConfig.swift +76 -0
- package/ios/vendor/AdvenueCore/SkanReporter.swift +25 -0
- package/ios/vendor/AdvenueCore/SkanState.swift +258 -0
- package/ios/vendor/AdvenueCore/Tcf.swift +48 -0
- package/ios/vendor/AdvenueCore/Transport.swift +14 -0
- package/ios/vendor/AdvenueFirebase/FirebaseAppInstanceId.swift +33 -0
- package/ios/vendor/AdvenuePlatform/AdvertisingIdentity.swift +87 -0
- package/ios/vendor/AdvenuePlatform/ChallengeFetcher.swift +42 -0
- package/ios/vendor/AdvenuePlatform/ConversionFetcher.swift +63 -0
- package/ios/vendor/AdvenuePlatform/CryptoKitSigner.swift +19 -0
- package/ios/vendor/AdvenuePlatform/DeviceCheckAttestation.swift +91 -0
- package/ios/vendor/AdvenuePlatform/DeviceInfo.swift +65 -0
- package/ios/vendor/AdvenuePlatform/ForegroundTracker.swift +55 -0
- package/ios/vendor/AdvenuePlatform/HttpTransport.swift +96 -0
- package/ios/vendor/AdvenuePlatform/Identity.swift +52 -0
- package/ios/vendor/AdvenuePlatform/InstallEnrichment.swift +143 -0
- package/ios/vendor/AdvenuePlatform/KeychainStore.swift +95 -0
- package/ios/vendor/AdvenuePlatform/SearchAdsToken.swift +76 -0
- package/ios/vendor/AdvenuePlatform/SkanConfigFetcher.swift +70 -0
- package/ios/vendor/AdvenuePlatform/StoreKitSkanReporter.swift +140 -0
- package/ios/vendor/AdvenuePlatform/SystemServices.swift +55 -0
- package/ios/vendor/AdvenuePlatform/TcfReader.swift +18 -0
- package/ios/vendor/AdvenuePlatform/UserDefaultsStore.swift +26 -0
- package/package.json +9 -11
- package/scripts/check-dist.mjs +17 -0
- package/scripts/check-vendored-swift.mjs +148 -0
- package/scripts/vendor-natives.mjs +149 -0
- package/scripts/vendor-natives.test.mjs +112 -0
- package/src/deep-links.ts +19 -1
- package/src/index.ts +267 -803
- package/src/native-types.ts +74 -171
- package/src/native.ts +0 -23
- package/src/types.ts +81 -0
- package/src/aem.ts +0 -33
- package/src/mmkv-storage.ts +0 -21
- package/src/native-storage.ts +0 -63
- package/src/secure-store.ts +0 -26
package/dist/index.js
CHANGED
|
@@ -51,174 +51,10 @@ var require_native_require = __commonJS({
|
|
|
51
51
|
}
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
// src/index.ts
|
|
55
|
-
import {
|
|
56
|
-
extractReferrerProperties,
|
|
57
|
-
parseInstallReferrer,
|
|
58
|
-
parseMetaInstallReferrer
|
|
59
|
-
} from "@advenue/install-referrer";
|
|
60
|
-
import {
|
|
61
|
-
AdvenueClient,
|
|
62
|
-
DEFAULT_ENDPOINT,
|
|
63
|
-
DEVICE_ID_KEY,
|
|
64
|
-
MemoryStorage,
|
|
65
|
-
resolveDurableDeviceId,
|
|
66
|
-
tcfToConsent
|
|
67
|
-
} from "@advenue/sdk-core";
|
|
68
|
-
|
|
69
|
-
// ../signing/src/index.ts
|
|
70
|
-
var K = new Uint32Array([
|
|
71
|
-
1116352408,
|
|
72
|
-
1899447441,
|
|
73
|
-
3049323471,
|
|
74
|
-
3921009573,
|
|
75
|
-
961987163,
|
|
76
|
-
1508970993,
|
|
77
|
-
2453635748,
|
|
78
|
-
2870763221,
|
|
79
|
-
3624381080,
|
|
80
|
-
310598401,
|
|
81
|
-
607225278,
|
|
82
|
-
1426881987,
|
|
83
|
-
1925078388,
|
|
84
|
-
2162078206,
|
|
85
|
-
2614888103,
|
|
86
|
-
3248222580,
|
|
87
|
-
3835390401,
|
|
88
|
-
4022224774,
|
|
89
|
-
264347078,
|
|
90
|
-
604807628,
|
|
91
|
-
770255983,
|
|
92
|
-
1249150122,
|
|
93
|
-
1555081692,
|
|
94
|
-
1996064986,
|
|
95
|
-
2554220882,
|
|
96
|
-
2821834349,
|
|
97
|
-
2952996808,
|
|
98
|
-
3210313671,
|
|
99
|
-
3336571891,
|
|
100
|
-
3584528711,
|
|
101
|
-
113926993,
|
|
102
|
-
338241895,
|
|
103
|
-
666307205,
|
|
104
|
-
773529912,
|
|
105
|
-
1294757372,
|
|
106
|
-
1396182291,
|
|
107
|
-
1695183700,
|
|
108
|
-
1986661051,
|
|
109
|
-
2177026350,
|
|
110
|
-
2456956037,
|
|
111
|
-
2730485921,
|
|
112
|
-
2820302411,
|
|
113
|
-
3259730800,
|
|
114
|
-
3345764771,
|
|
115
|
-
3516065817,
|
|
116
|
-
3600352804,
|
|
117
|
-
4094571909,
|
|
118
|
-
275423344,
|
|
119
|
-
430227734,
|
|
120
|
-
506948616,
|
|
121
|
-
659060556,
|
|
122
|
-
883997877,
|
|
123
|
-
958139571,
|
|
124
|
-
1322822218,
|
|
125
|
-
1537002063,
|
|
126
|
-
1747873779,
|
|
127
|
-
1955562222,
|
|
128
|
-
2024104815,
|
|
129
|
-
2227730452,
|
|
130
|
-
2361852424,
|
|
131
|
-
2428436474,
|
|
132
|
-
2756734187,
|
|
133
|
-
3204031479,
|
|
134
|
-
3329325298
|
|
135
|
-
]);
|
|
136
|
-
function rotr(x, n) {
|
|
137
|
-
return x >>> n | x << 32 - n;
|
|
138
|
-
}
|
|
139
|
-
function sha256Bytes(msg) {
|
|
140
|
-
const h = new Uint32Array([
|
|
141
|
-
1779033703,
|
|
142
|
-
3144134277,
|
|
143
|
-
1013904242,
|
|
144
|
-
2773480762,
|
|
145
|
-
1359893119,
|
|
146
|
-
2600822924,
|
|
147
|
-
528734635,
|
|
148
|
-
1541459225
|
|
149
|
-
]);
|
|
150
|
-
const l = msg.length;
|
|
151
|
-
const bitLen = l * 8;
|
|
152
|
-
const withOne = l + 1;
|
|
153
|
-
const padTo = (56 - withOne % 64 + 64) % 64;
|
|
154
|
-
const padded = new Uint8Array(withOne + padTo + 8);
|
|
155
|
-
padded.set(msg);
|
|
156
|
-
padded[l] = 128;
|
|
157
|
-
const dv = new DataView(padded.buffer);
|
|
158
|
-
dv.setUint32(padded.length - 8, Math.floor(bitLen / 4294967296));
|
|
159
|
-
dv.setUint32(padded.length - 4, bitLen >>> 0);
|
|
160
|
-
const w = new Uint32Array(64);
|
|
161
|
-
for (let i = 0; i < padded.length; i += 64) {
|
|
162
|
-
for (let t = 0; t < 16; t++) w[t] = dv.getUint32(i + t * 4);
|
|
163
|
-
for (let t = 16; t < 64; t++) {
|
|
164
|
-
const w15 = w[t - 15];
|
|
165
|
-
const w2 = w[t - 2];
|
|
166
|
-
const s0 = rotr(w15, 7) ^ rotr(w15, 18) ^ w15 >>> 3;
|
|
167
|
-
const s1 = rotr(w2, 17) ^ rotr(w2, 19) ^ w2 >>> 10;
|
|
168
|
-
w[t] = w[t - 16] + s0 + w[t - 7] + s1 >>> 0;
|
|
169
|
-
}
|
|
170
|
-
let a = h[0];
|
|
171
|
-
let b = h[1];
|
|
172
|
-
let c = h[2];
|
|
173
|
-
let d = h[3];
|
|
174
|
-
let e = h[4];
|
|
175
|
-
let f = h[5];
|
|
176
|
-
let g = h[6];
|
|
177
|
-
let hh = h[7];
|
|
178
|
-
for (let t = 0; t < 64; t++) {
|
|
179
|
-
const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
|
|
180
|
-
const ch = e & f ^ ~e & g;
|
|
181
|
-
const temp1 = hh + S1 + ch + K[t] + w[t] >>> 0;
|
|
182
|
-
const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
|
|
183
|
-
const maj = a & b ^ a & c ^ b & c;
|
|
184
|
-
const temp2 = S0 + maj >>> 0;
|
|
185
|
-
hh = g;
|
|
186
|
-
g = f;
|
|
187
|
-
f = e;
|
|
188
|
-
e = d + temp1 >>> 0;
|
|
189
|
-
d = c;
|
|
190
|
-
c = b;
|
|
191
|
-
b = a;
|
|
192
|
-
a = temp1 + temp2 >>> 0;
|
|
193
|
-
}
|
|
194
|
-
h[0] = h[0] + a >>> 0;
|
|
195
|
-
h[1] = h[1] + b >>> 0;
|
|
196
|
-
h[2] = h[2] + c >>> 0;
|
|
197
|
-
h[3] = h[3] + d >>> 0;
|
|
198
|
-
h[4] = h[4] + e >>> 0;
|
|
199
|
-
h[5] = h[5] + f >>> 0;
|
|
200
|
-
h[6] = h[6] + g >>> 0;
|
|
201
|
-
h[7] = h[7] + hh >>> 0;
|
|
202
|
-
}
|
|
203
|
-
const out = new Uint8Array(32);
|
|
204
|
-
const odv = new DataView(out.buffer);
|
|
205
|
-
for (let i = 0; i < 8; i++) odv.setUint32(i * 4, h[i]);
|
|
206
|
-
return out;
|
|
207
|
-
}
|
|
208
|
-
function toHex(bytes) {
|
|
209
|
-
let s = "";
|
|
210
|
-
for (let i = 0; i < bytes.length; i++) s += bytes[i].toString(16).padStart(2, "0");
|
|
211
|
-
return s;
|
|
212
|
-
}
|
|
213
|
-
var enc = new TextEncoder();
|
|
214
|
-
function sha256Hex(message) {
|
|
215
|
-
return toHex(sha256Bytes(enc.encode(message)));
|
|
216
|
-
}
|
|
217
|
-
|
|
218
54
|
// package.json
|
|
219
55
|
var package_default = {
|
|
220
56
|
name: "@advenue/react-native",
|
|
221
|
-
version: "0.
|
|
57
|
+
version: "1.0.0",
|
|
222
58
|
description: "Advenue MMP React Native SDK \u2014 attribution, install tracking, and deep links (bundled iOS/Android Expo native modules)",
|
|
223
59
|
type: "module",
|
|
224
60
|
license: "MIT",
|
|
@@ -241,20 +77,20 @@ var package_default = {
|
|
|
241
77
|
"ios",
|
|
242
78
|
"android",
|
|
243
79
|
"expo-module.config.json",
|
|
244
|
-
"!**/*.test.ts"
|
|
80
|
+
"!**/*.test.ts",
|
|
81
|
+
"ios/vendor",
|
|
82
|
+
"android/src/main/kotlin"
|
|
245
83
|
],
|
|
246
84
|
publishConfig: {
|
|
247
85
|
access: "public"
|
|
248
86
|
},
|
|
249
87
|
scripts: {
|
|
250
|
-
build: "tsup && node scripts/check-dist.mjs",
|
|
88
|
+
build: "node scripts/vendor-natives.mjs && node scripts/check-vendored-swift.mjs && tsup && node scripts/check-dist.mjs",
|
|
251
89
|
typecheck: "tsc --noEmit",
|
|
252
|
-
test: "vitest run"
|
|
253
|
-
|
|
254
|
-
dependencies: {
|
|
255
|
-
"@advenue/install-referrer": "workspace:*",
|
|
256
|
-
"@advenue/sdk-core": "workspace:*"
|
|
90
|
+
test: "vitest run --minWorkers=1 --maxWorkers=2 && node --test scripts/vendor-natives.test.mjs && node scripts/vendor-natives.mjs && node scripts/check-vendored-swift.mjs",
|
|
91
|
+
vendor: "node scripts/vendor-natives.mjs"
|
|
257
92
|
},
|
|
93
|
+
dependencies: {},
|
|
258
94
|
peerDependencies: {
|
|
259
95
|
"@expo/config-plugins": ">=8",
|
|
260
96
|
react: ">=18.2",
|
|
@@ -270,8 +106,6 @@ var package_default = {
|
|
|
270
106
|
}
|
|
271
107
|
},
|
|
272
108
|
devDependencies: {
|
|
273
|
-
"@advenue/shared": "workspace:*",
|
|
274
|
-
"@advenue/signing": "workspace:*",
|
|
275
109
|
tsup: "^8.5.1",
|
|
276
110
|
typescript: "^5.7.2",
|
|
277
111
|
vitest: "^2.1.8"
|
|
@@ -279,18 +113,15 @@ var package_default = {
|
|
|
279
113
|
"react-native": "./dist/index.cjs"
|
|
280
114
|
};
|
|
281
115
|
|
|
282
|
-
// src/aem.ts
|
|
283
|
-
function extractAemCampaignIds(alApplinkData) {
|
|
284
|
-
try {
|
|
285
|
-
const parsed = JSON.parse(alApplinkData);
|
|
286
|
-
const value = typeof parsed.campaign_ids === "string" && parsed.campaign_ids ? parsed.campaign_ids : typeof parsed.extras?.campaign_ids === "string" && parsed.extras.campaign_ids ? parsed.extras.campaign_ids : null;
|
|
287
|
-
return value && value.length <= 2048 ? value : null;
|
|
288
|
-
} catch {
|
|
289
|
-
return null;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
116
|
// src/deep-links.ts
|
|
117
|
+
var ALLOWED_QUERY_KEYS = /* @__PURE__ */ new Set([
|
|
118
|
+
"ref",
|
|
119
|
+
"campaign",
|
|
120
|
+
"network",
|
|
121
|
+
"influencer_id",
|
|
122
|
+
"influencerId",
|
|
123
|
+
"al_applink_data"
|
|
124
|
+
]);
|
|
294
125
|
function parseDirectLink(url) {
|
|
295
126
|
let deepLinkValue = "";
|
|
296
127
|
let params;
|
|
@@ -300,6 +131,7 @@ function parseDirectLink(url) {
|
|
|
300
131
|
const isHttp = parsed.protocol === "http:" || parsed.protocol === "https:";
|
|
301
132
|
deepLinkValue = isHttp ? path : [parsed.host, path].filter(Boolean).join("/");
|
|
302
133
|
parsed.searchParams.forEach((v, k) => {
|
|
134
|
+
if (!ALLOWED_QUERY_KEYS.has(k)) return;
|
|
303
135
|
params ??= {};
|
|
304
136
|
params[k] = v;
|
|
305
137
|
});
|
|
@@ -335,15 +167,6 @@ function setupDeepLinks(setup) {
|
|
|
335
167
|
return { remove: () => listener.remove(), ready };
|
|
336
168
|
}
|
|
337
169
|
|
|
338
|
-
// src/mmkv-storage.ts
|
|
339
|
-
function createMMKVStorage(mmkv) {
|
|
340
|
-
return {
|
|
341
|
-
getItem: (key) => mmkv.getString(key) ?? null,
|
|
342
|
-
setItem: (key, value) => mmkv.set(key, value),
|
|
343
|
-
removeItem: (key) => mmkv.delete(key)
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
|
|
347
170
|
// src/native.ts
|
|
348
171
|
var import_native_require = __toESM(require_native_require(), 1);
|
|
349
172
|
function getIosNative() {
|
|
@@ -370,27 +193,6 @@ function getPlatformOS() {
|
|
|
370
193
|
return null;
|
|
371
194
|
}
|
|
372
195
|
}
|
|
373
|
-
function getOsVersion() {
|
|
374
|
-
try {
|
|
375
|
-
const rn = (0, import_native_require.requireReactNative)();
|
|
376
|
-
if (!rn) return null;
|
|
377
|
-
if (rn.Platform.OS === "android") {
|
|
378
|
-
const release = rn.Platform.constants?.Release;
|
|
379
|
-
return release != null ? String(release) : null;
|
|
380
|
-
}
|
|
381
|
-
return rn.Platform.Version != null ? String(rn.Platform.Version) : null;
|
|
382
|
-
} catch {
|
|
383
|
-
return null;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
function getAppState() {
|
|
387
|
-
try {
|
|
388
|
-
const rn = (0, import_native_require.requireReactNative)();
|
|
389
|
-
return rn?.AppState ?? null;
|
|
390
|
-
} catch {
|
|
391
|
-
return null;
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
196
|
function getLinking() {
|
|
395
197
|
try {
|
|
396
198
|
const rn = (0, import_native_require.requireReactNative)();
|
|
@@ -400,489 +202,208 @@ function getLinking() {
|
|
|
400
202
|
}
|
|
401
203
|
}
|
|
402
204
|
|
|
403
|
-
// src/native-storage.ts
|
|
404
|
-
function createNativeStorage(mod) {
|
|
405
|
-
const m = mod;
|
|
406
|
-
if (!m || typeof m.storageGetItem !== "function" || typeof m.storageSetItem !== "function" || typeof m.storageRemoveItem !== "function") {
|
|
407
|
-
return null;
|
|
408
|
-
}
|
|
409
|
-
return {
|
|
410
|
-
getItem: (key) => m.storageGetItem?.(key) ?? null,
|
|
411
|
-
setItem: (key, value) => m.storageSetItem?.(key, value),
|
|
412
|
-
removeItem: (key) => m.storageRemoveItem?.(key)
|
|
413
|
-
};
|
|
414
|
-
}
|
|
415
|
-
function createNativeSecureStore(mod) {
|
|
416
|
-
const m = mod;
|
|
417
|
-
if (!m || typeof m.secureGetItem !== "function" || typeof m.secureSetItem !== "function" || typeof m.secureRemoveItem !== "function") {
|
|
418
|
-
return null;
|
|
419
|
-
}
|
|
420
|
-
return {
|
|
421
|
-
getItemAsync: async (key) => m.secureGetItem?.(key) ?? null,
|
|
422
|
-
setItemAsync: async (key, value) => m.secureSetItem?.(key, value),
|
|
423
|
-
deleteItemAsync: async (key) => m.secureRemoveItem?.(key)
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// src/secure-store.ts
|
|
428
|
-
function createSecureStore(secureStore2) {
|
|
429
|
-
return {
|
|
430
|
-
getItemAsync: async (key) => await secureStore2.getItemAsync(key) ?? null,
|
|
431
|
-
setItemAsync: (key, value) => secureStore2.setItemAsync(key, value),
|
|
432
|
-
...secureStore2.deleteItemAsync ? {
|
|
433
|
-
deleteItemAsync: (key) => secureStore2.deleteItemAsync?.(key) ?? Promise.resolve()
|
|
434
|
-
} : {}
|
|
435
|
-
};
|
|
436
|
-
}
|
|
437
|
-
|
|
438
205
|
// src/index.ts
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
client.setAdvertisingId({});
|
|
448
|
-
return;
|
|
449
|
-
}
|
|
450
|
-
const ios = getIosNative();
|
|
451
|
-
if (ios) {
|
|
452
|
-
const idfa = ios.getTrackingAuthorizationStatus() === "authorized" ? await ios.getAdvertisingId() : null;
|
|
453
|
-
const vendorId = typeof ios.getIdentifierForVendor === "function" ? ios.getIdentifierForVendor() : null;
|
|
454
|
-
client.setAdvertisingId({ ...idfa ? { idfa } : {}, ...vendorId ? { vendorId } : {} });
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
const android = getAndroidNative();
|
|
458
|
-
if (android && typeof android.getAdvertisingId === "function") {
|
|
459
|
-
const r = await android.getAdvertisingId();
|
|
460
|
-
const vendorId = typeof android.getAppSetId === "function" ? await android.getAppSetId() : null;
|
|
461
|
-
const adFields = r ? r.limitAdTracking ? { limitAdTracking: true } : { gaid: r.id } : {};
|
|
462
|
-
const hasUsableGaid = !!r && !r.limitAdTracking;
|
|
463
|
-
const rawAndroidId = !hasUsableGaid && typeof android.getAndroidId === "function" ? android.getAndroidId() : null;
|
|
464
|
-
const androidId = rawAndroidId && /^[0-9a-fA-F]{8,32}$/.test(rawAndroidId) ? rawAndroidId : null;
|
|
465
|
-
client.setAdvertisingId({
|
|
466
|
-
...adFields,
|
|
467
|
-
...vendorId ? { vendorId } : {},
|
|
468
|
-
...androidId ? { androidId } : {}
|
|
469
|
-
});
|
|
470
|
-
return;
|
|
471
|
-
}
|
|
472
|
-
client.setAdvertisingId({});
|
|
473
|
-
}
|
|
474
|
-
function consentEquals(a, b) {
|
|
475
|
-
return a.isUserSubjectToGDPR === b.isUserSubjectToGDPR && a.hasConsentForDataUsage === b.hasConsentForDataUsage && a.hasConsentForAdsPersonalization === b.hasConsentForAdsPersonalization && a.hasConsentForAdStorage === b.hasConsentForAdStorage;
|
|
206
|
+
var IGNORED_OPTIONS = ["mmkv", "secureStore", "sdkConfigFetcher", "tcfDataCollection"];
|
|
207
|
+
var started = false;
|
|
208
|
+
var deepLinkSub = null;
|
|
209
|
+
var errorSub = null;
|
|
210
|
+
var onErrorHook;
|
|
211
|
+
var consentCache = false;
|
|
212
|
+
function bridge() {
|
|
213
|
+
return { ios: getIosNative(), android: getAndroidNative() };
|
|
476
214
|
}
|
|
477
|
-
function
|
|
478
|
-
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
215
|
+
function call(name, ...args) {
|
|
216
|
+
const { ios, android } = bridge();
|
|
217
|
+
for (const mod of [ios, android]) {
|
|
218
|
+
const fn = mod?.[name];
|
|
219
|
+
if (typeof fn === "function") {
|
|
220
|
+
try {
|
|
221
|
+
return fn(...args);
|
|
222
|
+
} catch (error) {
|
|
223
|
+
report(`bridge.${name}`, error);
|
|
224
|
+
return void 0;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
487
227
|
}
|
|
488
|
-
|
|
489
|
-
const client = active();
|
|
490
|
-
const current = client.getConsentData();
|
|
491
|
-
if (current && consentEquals(current, consent)) return null;
|
|
492
|
-
client.setConsentData(consent);
|
|
493
|
-
void resolveAdvertisingId().catch((err) => reportError("enrich.advertisingId", err));
|
|
494
|
-
return consent;
|
|
228
|
+
return void 0;
|
|
495
229
|
}
|
|
496
|
-
function
|
|
230
|
+
function report(context, cause) {
|
|
497
231
|
try {
|
|
498
|
-
|
|
499
|
-
return natives.android.getDeviceInfo();
|
|
500
|
-
}
|
|
501
|
-
if (natives.platform === "ios" && natives.ios?.getDeviceInfo) {
|
|
502
|
-
return natives.ios.getDeviceInfo();
|
|
503
|
-
}
|
|
232
|
+
onErrorHook?.(context, cause);
|
|
504
233
|
} catch {
|
|
505
234
|
}
|
|
506
|
-
return {};
|
|
507
|
-
}
|
|
508
|
-
function applyAppState(client, status) {
|
|
509
|
-
if (status === "active") {
|
|
510
|
-
client.notifyAppActive();
|
|
511
|
-
} else if (status === "background") {
|
|
512
|
-
client.notifyAppBackground();
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
var instance = null;
|
|
516
|
-
var appStateSub = null;
|
|
517
|
-
var deepLinkSub = null;
|
|
518
|
-
var secureStore = null;
|
|
519
|
-
var installFlagStore = null;
|
|
520
|
-
var INSTALL_SENT_KEY = "advenue.install_sent";
|
|
521
|
-
var installInFlight = false;
|
|
522
|
-
var autoInstallPending = false;
|
|
523
|
-
var autoInstallEnabled = true;
|
|
524
|
-
var manualConsentSet = false;
|
|
525
|
-
var tcfCollectionEnabled = false;
|
|
526
|
-
var configuredAppId = null;
|
|
527
|
-
var configuredApiKey = null;
|
|
528
|
-
var configuredEndpoint = DEFAULT_ENDPOINT;
|
|
529
|
-
var aemSeenUrlHashes = /* @__PURE__ */ new Set();
|
|
530
|
-
function active() {
|
|
531
|
-
if (!instance) {
|
|
532
|
-
throw new Error("Advenue.initialize() must be called before tracking events.");
|
|
533
|
-
}
|
|
534
|
-
return instance;
|
|
535
235
|
}
|
|
536
|
-
function
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
void trackInstall().catch((err) => reportError("install.auto", err));
|
|
541
|
-
}
|
|
542
|
-
function resolvePlatform(explicit) {
|
|
543
|
-
if (explicit) {
|
|
544
|
-
return explicit;
|
|
545
|
-
}
|
|
546
|
-
const os = getPlatformOS();
|
|
547
|
-
if (os === "ios" || os === "android") {
|
|
548
|
-
return os;
|
|
549
|
-
}
|
|
550
|
-
if (os) {
|
|
551
|
-
return "web";
|
|
552
|
-
}
|
|
553
|
-
throw new Error(
|
|
554
|
-
"Advenue.initialize(): platform could not be detected (react-native unavailable) \u2014 pass platform: 'ios' | 'android' | 'web'."
|
|
555
|
-
);
|
|
556
|
-
}
|
|
557
|
-
function fireAutoInstallIfPending() {
|
|
558
|
-
if (!autoInstallPending) {
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
autoInstallPending = false;
|
|
562
|
-
fireAutoInstall();
|
|
236
|
+
function requireStarted() {
|
|
237
|
+
if (started) return true;
|
|
238
|
+
report("sdk.notInitialized", new Error("Advenue.initialize() has not been called"));
|
|
239
|
+
return false;
|
|
563
240
|
}
|
|
564
241
|
var Advenue = {
|
|
242
|
+
/**
|
|
243
|
+
* Starts the SDK. Safe to call from the app's entry point, and safe to call
|
|
244
|
+
* twice: the native side replaces its previous instance.
|
|
245
|
+
*/
|
|
565
246
|
async initialize(config) {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
...rest
|
|
574
|
-
} = config;
|
|
575
|
-
autoInstallPending = false;
|
|
576
|
-
manualConsentSet = false;
|
|
577
|
-
tcfCollectionEnabled = tcfDataCollection === true;
|
|
578
|
-
autoInstallEnabled = autoTrackInstall !== false;
|
|
579
|
-
const platform = resolvePlatform(rest.platform);
|
|
580
|
-
configuredAppId = appId ?? null;
|
|
581
|
-
configuredApiKey = config.apiKey;
|
|
582
|
-
configuredEndpoint = config.endpoint ?? DEFAULT_ENDPOINT;
|
|
583
|
-
appStateSub?.remove();
|
|
584
|
-
appStateSub = null;
|
|
585
|
-
deepLinkSub?.remove();
|
|
586
|
-
deepLinkSub = null;
|
|
587
|
-
instance?.shutdown();
|
|
588
|
-
const iosMod = getIosNative();
|
|
589
|
-
const androidMod = getAndroidNative();
|
|
590
|
-
const storage = mmkv ? createMMKVStorage(mmkv) : createNativeStorage(iosMod ?? androidMod) ?? new MemoryStorage();
|
|
591
|
-
installFlagStore = storage;
|
|
592
|
-
secureStore = secureMod ? createSecureStore(secureMod) : createNativeSecureStore(iosMod);
|
|
593
|
-
const deviceId = rest.deviceId ?? await resolveDurableDeviceId(storage, secureStore ?? void 0);
|
|
594
|
-
const osVersion = rest.osVersion ?? getOsVersion() ?? void 0;
|
|
595
|
-
instance = new AdvenueClient({
|
|
596
|
-
...rest,
|
|
597
|
-
platform,
|
|
598
|
-
deviceId,
|
|
599
|
-
storage,
|
|
600
|
-
...osVersion ? { osVersion } : {}
|
|
601
|
-
});
|
|
602
|
-
instance.debugLog(`SDK v${package_default.version} \u2014 events -> ${configuredEndpoint}`);
|
|
603
|
-
if (tcfCollectionEnabled) resolveDmaConsent();
|
|
604
|
-
void resolveAdvertisingId().catch((err) => reportError("enrich.advertisingId", err));
|
|
605
|
-
const deviceInfo = collectDeviceInfo({
|
|
606
|
-
platform,
|
|
607
|
-
ios: getIosNative(),
|
|
608
|
-
android: getAndroidNative()
|
|
609
|
-
});
|
|
610
|
-
if (Object.keys(deviceInfo).length > 0) instance.setDeviceInfo(deviceInfo);
|
|
611
|
-
if (!config.disableAutoSessions) {
|
|
612
|
-
const appState = getAppState();
|
|
613
|
-
if (appState) {
|
|
614
|
-
appStateSub?.remove();
|
|
615
|
-
let seenBackground = false;
|
|
616
|
-
const handler = (status) => {
|
|
617
|
-
if (!instance) return;
|
|
618
|
-
if (status === "background") {
|
|
619
|
-
seenBackground = true;
|
|
620
|
-
if (tcfCollectionEnabled) resolveDmaConsent();
|
|
621
|
-
applyAppState(instance, status);
|
|
622
|
-
} else if (status === "active") {
|
|
623
|
-
if (!seenBackground) return;
|
|
624
|
-
seenBackground = false;
|
|
625
|
-
if (tcfCollectionEnabled) resolveDmaConsent();
|
|
626
|
-
applyAppState(instance, status);
|
|
627
|
-
void resolveAdvertisingId().catch((err) => reportError("enrich.advertisingId", err));
|
|
628
|
-
}
|
|
629
|
-
};
|
|
630
|
-
appStateSub = appState.addEventListener("change", handler);
|
|
631
|
-
instance.notifyAppActive();
|
|
632
|
-
} else {
|
|
633
|
-
instance.notifyAppActive();
|
|
247
|
+
onErrorHook = config.onError;
|
|
248
|
+
for (const option of IGNORED_OPTIONS) {
|
|
249
|
+
if (config[option] !== void 0) {
|
|
250
|
+
report(
|
|
251
|
+
`config.ignored:${option}`,
|
|
252
|
+
new Error(`${option} is decided by the native SDK and has no effect`)
|
|
253
|
+
);
|
|
634
254
|
}
|
|
635
255
|
}
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
client.track("adv_meta_aem", { campaignIds, sourceUrlHash });
|
|
657
|
-
aemSeenUrlHashes.add(sourceUrlHash);
|
|
658
|
-
}
|
|
256
|
+
Advenue.shutdown();
|
|
257
|
+
call("bridgeInitialize", {
|
|
258
|
+
apiKey: config.apiKey,
|
|
259
|
+
endpoint: config.endpoint,
|
|
260
|
+
appVersion: config.appVersion,
|
|
261
|
+
requireConsent: config.requireConsent ?? false,
|
|
262
|
+
batchSize: config.batchSize,
|
|
263
|
+
flushIntervalMs: config.flushIntervalMs,
|
|
264
|
+
signingSecret: config.signingSecret,
|
|
265
|
+
fbAppId: config.fbAppId,
|
|
266
|
+
autoTrackInstall: config.autoTrackInstall !== false,
|
|
267
|
+
sdkVersion: package_default.version
|
|
268
|
+
});
|
|
269
|
+
started = true;
|
|
270
|
+
const { ios: iosForErrors, android: androidForErrors } = bridge();
|
|
271
|
+
const emitter = iosForErrors ?? androidForErrors;
|
|
272
|
+
if (typeof emitter?.addListener === "function") {
|
|
273
|
+
try {
|
|
274
|
+
errorSub = emitter.addListener("onAdvenueError", (event) => {
|
|
275
|
+
report(event.context, new Error(event.message));
|
|
659
276
|
});
|
|
660
|
-
|
|
277
|
+
} catch (error) {
|
|
278
|
+
report("diagnostics.subscribe", error);
|
|
661
279
|
}
|
|
662
280
|
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
281
|
+
consentCache = call("bridgeGetConsent") ?? false;
|
|
282
|
+
if (config.appInstanceIdProvider) {
|
|
283
|
+
try {
|
|
284
|
+
const id = await config.appInstanceIdProvider();
|
|
285
|
+
if (id) call("bridgeSetAppInstanceId", id);
|
|
286
|
+
} catch (error) {
|
|
287
|
+
report("enrich.appInstanceId", error);
|
|
669
288
|
}
|
|
670
289
|
}
|
|
671
|
-
|
|
290
|
+
const linking = getLinking();
|
|
291
|
+
if (linking) {
|
|
292
|
+
deepLinkSub = setupDeepLinks({
|
|
293
|
+
getInitialURL: () => linking.getInitialURL(),
|
|
294
|
+
addUrlListener: (handler) => linking.addEventListener("url", (e) => handler(e.url)),
|
|
295
|
+
resolveDeferred: () => Advenue.resolveDeferredDeepLink(),
|
|
296
|
+
onDeepLink: config.onDeepLink ?? (() => {
|
|
297
|
+
}),
|
|
298
|
+
onDirectUrl: (url) => {
|
|
299
|
+
call("bridgeProcessDeepLink", url);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
deepLinkSub.ready.catch((error) => report("deepLink.resolve", error));
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
track(name, properties) {
|
|
306
|
+
if (!requireStarted()) return;
|
|
307
|
+
call("bridgeTrack", name, properties ?? null);
|
|
308
|
+
},
|
|
309
|
+
/** Adds exact local revenue to Apple's conversion-value state. iOS only. */
|
|
310
|
+
async recordSkanRevenue(input) {
|
|
311
|
+
if (!requireStarted()) return;
|
|
312
|
+
call("bridgeRecordSkanRevenue", input.amount, input.currency);
|
|
313
|
+
},
|
|
314
|
+
setAppInstanceId(id) {
|
|
315
|
+
if (!requireStarted()) return;
|
|
316
|
+
call("bridgeSetAppInstanceId", id);
|
|
672
317
|
},
|
|
673
|
-
track: (name, properties, opts) => active().track(name, properties, opts),
|
|
674
318
|
/**
|
|
675
|
-
*
|
|
676
|
-
*
|
|
319
|
+
* Cross-device linking: associates subsequent events with your user id.
|
|
320
|
+
* Pass null to clear.
|
|
321
|
+
*
|
|
322
|
+
* New on this object. The previous release reached it through the client
|
|
323
|
+
* `initialize()` resolved to, and that client no longer exists — so it is
|
|
324
|
+
* promoted here rather than dropped, which is what an app following the
|
|
325
|
+
* documented cross-device recipe would otherwise hit at runtime.
|
|
326
|
+
*/
|
|
327
|
+
setUserId(id) {
|
|
328
|
+
if (!requireStarted()) return;
|
|
329
|
+
call("bridgeSetUserId", id);
|
|
330
|
+
},
|
|
331
|
+
/**
|
|
332
|
+
* Registers the device's push token for uninstall measurement.
|
|
333
|
+
*
|
|
334
|
+
* Advenue never requests the notification permission and never displays
|
|
335
|
+
* anything: pass the token your push library already produced, on every
|
|
336
|
+
* launch and from its refresh listener. A stale token is the one thing that
|
|
337
|
+
* makes uninstall measurement report churn that did not happen.
|
|
338
|
+
*/
|
|
339
|
+
setPushToken(token, provider) {
|
|
340
|
+
if (!requireStarted()) return;
|
|
341
|
+
call("bridgeSetPushToken", token, provider ?? null);
|
|
342
|
+
},
|
|
343
|
+
/**
|
|
344
|
+
* Shows the iOS ATT prompt. Where ATT does not exist (non-iOS, or the iOS
|
|
345
|
+
* module is absent) there is no prompt to show and no signal to read, so
|
|
346
|
+
* consent is left untouched and the call resolves 'unavailable'.
|
|
677
347
|
*/
|
|
678
348
|
async requestTrackingAuthorization() {
|
|
679
|
-
const ios =
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
if (status === "authorized") {
|
|
684
|
-
fireAutoInstallIfPending();
|
|
685
|
-
}
|
|
349
|
+
const { ios } = bridge();
|
|
350
|
+
if (!ios) return "unavailable";
|
|
351
|
+
const status = await ios.requestTrackingAuthorization();
|
|
352
|
+
Advenue.setTrackingConsent(status === "authorized");
|
|
686
353
|
return status;
|
|
687
354
|
},
|
|
688
355
|
setTrackingConsent(granted) {
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
356
|
+
if (!requireStarted()) return;
|
|
357
|
+
consentCache = granted;
|
|
358
|
+
call("bridgeSetConsent", granted);
|
|
359
|
+
},
|
|
360
|
+
getTrackingConsent: () => consentCache,
|
|
361
|
+
setConsentData(consent) {
|
|
362
|
+
if (!requireStarted()) return;
|
|
363
|
+
call("bridgeSetConsentData", consent);
|
|
693
364
|
},
|
|
694
|
-
|
|
695
|
-
/** GDPR/CCPA erasure:
|
|
365
|
+
getConsentData: () => call("bridgeGetConsentData") ?? null,
|
|
366
|
+
/** GDPR/CCPA erasure: stops tracking and wipes local identifiers and queue. */
|
|
696
367
|
forgetMe() {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
} catch (err) {
|
|
701
|
-
reportError("forget.wipe", err);
|
|
702
|
-
}
|
|
703
|
-
const secure = secureStore;
|
|
704
|
-
if (secure?.deleteItemAsync) {
|
|
705
|
-
for (const key of [DEVICE_ID_KEY, INSTALL_SENT_KEY]) {
|
|
706
|
-
void secure.deleteItemAsync(key).catch((err) => reportError("forget.secureWipe", err));
|
|
707
|
-
}
|
|
708
|
-
}
|
|
368
|
+
if (!requireStarted()) return;
|
|
369
|
+
call("bridgeForgetMe");
|
|
370
|
+
consentCache = false;
|
|
709
371
|
},
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
372
|
+
flush() {
|
|
373
|
+
if (!requireStarted()) return;
|
|
374
|
+
call("bridgeFlush");
|
|
375
|
+
},
|
|
376
|
+
getDeviceId: () => Promise.resolve(
|
|
377
|
+
call("bridgeDeviceId") ?? null
|
|
378
|
+
),
|
|
379
|
+
/** The Advenue ID — alias of `getDeviceId`. */
|
|
380
|
+
getAdvenueId: () => Advenue.getDeviceId(),
|
|
381
|
+
/** Which app the server resolved this API key to; null until a batch lands. */
|
|
382
|
+
getResolvedAppId: () => call("bridgeResolvedAppId") ?? null,
|
|
383
|
+
/**
|
|
384
|
+
* Resolves the deferred deep link for this install, or null for an organic
|
|
385
|
+
* one — which is most of them.
|
|
386
|
+
*/
|
|
387
|
+
async resolveDeferredDeepLink() {
|
|
388
|
+
if (!requireStarted()) return null;
|
|
389
|
+
const result = call("bridgeResolveDeferredDeepLink");
|
|
390
|
+
return await result ?? null;
|
|
714
391
|
},
|
|
715
|
-
getConsentData: () => active().getConsentData(),
|
|
716
|
-
flush: () => active().flush(),
|
|
717
|
-
getDeviceId: () => active().getDeviceId(),
|
|
718
|
-
/** The Advenue ID — alias of getDeviceId (see AdvenueClient.getAdvenueId). */
|
|
719
|
-
getAdvenueId: () => active().getAdvenueId(),
|
|
720
392
|
shutdown() {
|
|
721
|
-
appStateSub?.remove();
|
|
722
|
-
appStateSub = null;
|
|
723
393
|
deepLinkSub?.remove();
|
|
724
394
|
deepLinkSub = null;
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
autoInstallEnabled = true;
|
|
731
|
-
manualConsentSet = false;
|
|
732
|
-
tcfCollectionEnabled = false;
|
|
733
|
-
configuredAppId = null;
|
|
734
|
-
configuredApiKey = null;
|
|
735
|
-
configuredEndpoint = DEFAULT_ENDPOINT;
|
|
736
|
-
aemSeenUrlHashes.clear();
|
|
395
|
+
errorSub?.remove();
|
|
396
|
+
errorSub = null;
|
|
397
|
+
if (started) call("bridgeShutdown");
|
|
398
|
+
started = false;
|
|
399
|
+
consentCache = false;
|
|
737
400
|
}
|
|
738
401
|
};
|
|
739
|
-
|
|
740
|
-
const client = active();
|
|
741
|
-
if (client.getRequireConsent() && !client.getTrackingConsent()) {
|
|
742
|
-
return;
|
|
743
|
-
}
|
|
744
|
-
let sent = installFlagStore?.getItem(INSTALL_SENT_KEY) === "1";
|
|
745
|
-
if (!sent && secureStore) {
|
|
746
|
-
try {
|
|
747
|
-
sent = await secureStore.getItemAsync(INSTALL_SENT_KEY) === "1";
|
|
748
|
-
} catch (err) {
|
|
749
|
-
reportError("install.guardRead", err);
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
if (sent) {
|
|
753
|
-
client.debugLog("install skipped (already sent on this device)");
|
|
754
|
-
return;
|
|
755
|
-
}
|
|
756
|
-
if (installInFlight) {
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
installInFlight = true;
|
|
760
|
-
const opts = {};
|
|
761
|
-
const props = {};
|
|
762
|
-
const android = getAndroidNative();
|
|
763
|
-
if (android) {
|
|
764
|
-
try {
|
|
765
|
-
const result = await android.getInstallReferrer();
|
|
766
|
-
if (result) {
|
|
767
|
-
const parsed = parseInstallReferrer(result.referrer);
|
|
768
|
-
if (parsed.network) opts.network = parsed.network;
|
|
769
|
-
if (parsed.campaign) opts.campaign = parsed.campaign;
|
|
770
|
-
if (parsed.gclid) props.gclid = parsed.gclid;
|
|
771
|
-
if (parsed.fbclid) props.fbclid = parsed.fbclid;
|
|
772
|
-
Object.assign(props, extractReferrerProperties(result));
|
|
773
|
-
}
|
|
774
|
-
} catch (err) {
|
|
775
|
-
reportError("enrich.installReferrer", err);
|
|
776
|
-
}
|
|
777
|
-
try {
|
|
778
|
-
const meta = await android.getMetaInstallReferrer();
|
|
779
|
-
const parsedMeta = meta ? parseMetaInstallReferrer(meta) : null;
|
|
780
|
-
if (parsedMeta) {
|
|
781
|
-
props.metaInstallReferrer = parsedMeta.raw;
|
|
782
|
-
if (parsedMeta.encryptedData) props.metaReferrerData = parsedMeta.encryptedData;
|
|
783
|
-
if (parsedMeta.nonce) props.metaReferrerNonce = parsedMeta.nonce;
|
|
784
|
-
if (!opts.network && parsedMeta.isClickThrough) {
|
|
785
|
-
opts.network = "meta";
|
|
786
|
-
if (parsedMeta.campaign) opts.campaign = parsedMeta.campaign;
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
} catch (err) {
|
|
790
|
-
reportError("enrich.metaReferrer", err);
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
const ios = getIosNative();
|
|
794
|
-
if (ios) {
|
|
795
|
-
try {
|
|
796
|
-
ios.registerAppForAttribution();
|
|
797
|
-
} catch (err) {
|
|
798
|
-
reportError("enrich.skanRegister", err);
|
|
799
|
-
}
|
|
800
|
-
try {
|
|
801
|
-
const asaToken = await ios.getAttributionToken();
|
|
802
|
-
if (asaToken) {
|
|
803
|
-
opts.adservicesToken = asaToken;
|
|
804
|
-
}
|
|
805
|
-
} catch (err) {
|
|
806
|
-
reportError("enrich.adservicesToken", err);
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
await resolveAdvertisingId();
|
|
810
|
-
const trackOpts = { type: "install", ...opts };
|
|
811
|
-
if (configuredAppId && android && typeof android.getIntegrityToken === "function") {
|
|
812
|
-
try {
|
|
813
|
-
const deviceId = client.getDeviceId();
|
|
814
|
-
const requestHash = sha256Hex(`${configuredAppId}:${deviceId}`);
|
|
815
|
-
const token = await android.getIntegrityToken(requestHash);
|
|
816
|
-
if (token) {
|
|
817
|
-
trackOpts.attestationToken = token;
|
|
818
|
-
trackOpts.attestationType = "play-integrity";
|
|
819
|
-
}
|
|
820
|
-
} catch (err) {
|
|
821
|
-
reportError("attest.playIntegrity", err);
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
if (configuredAppId && configuredApiKey && ios && typeof ios.attestKey === "function") {
|
|
825
|
-
try {
|
|
826
|
-
const deviceId = client.getDeviceId();
|
|
827
|
-
const challengeUrl = `${configuredEndpoint}/v1/attest/challenge?deviceId=${encodeURIComponent(deviceId)}`;
|
|
828
|
-
const challengeRes = await fetch(challengeUrl, {
|
|
829
|
-
headers: { "x-api-key": configuredApiKey }
|
|
830
|
-
});
|
|
831
|
-
if (!challengeRes.ok) throw new Error(`challenge HTTP ${challengeRes.status}`);
|
|
832
|
-
const { challenge } = await challengeRes.json();
|
|
833
|
-
const { keyId, attestationObject } = await ios.attestKey(challenge);
|
|
834
|
-
trackOpts.attestationToken = attestationObject;
|
|
835
|
-
trackOpts.attestationType = "app-attest";
|
|
836
|
-
trackOpts.attestationKeyId = keyId;
|
|
837
|
-
trackOpts.attestationChallenge = challenge;
|
|
838
|
-
} catch (err) {
|
|
839
|
-
reportError("attest.appAttest", err);
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
if (ios && typeof ios.getDeviceCheckToken === "function") {
|
|
843
|
-
try {
|
|
844
|
-
const token = await ios.getDeviceCheckToken();
|
|
845
|
-
if (token) {
|
|
846
|
-
trackOpts.deviceCheckToken = token;
|
|
847
|
-
}
|
|
848
|
-
} catch (err) {
|
|
849
|
-
reportError("attest.deviceCheck", err);
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
const pendingBefore = client.pendingCount;
|
|
853
|
-
client.track("install", props, trackOpts);
|
|
854
|
-
if (client.pendingCount === pendingBefore) {
|
|
855
|
-
installInFlight = false;
|
|
856
|
-
client.debugLog("install dropped (consent revoked mid-flight)");
|
|
857
|
-
if (autoInstallEnabled && client.getRequireConsent() && !client.getTrackingConsent()) {
|
|
858
|
-
autoInstallPending = true;
|
|
859
|
-
}
|
|
860
|
-
return;
|
|
861
|
-
}
|
|
862
|
-
client.debugLog("install fired");
|
|
863
|
-
try {
|
|
864
|
-
installFlagStore?.setItem(INSTALL_SENT_KEY, "1");
|
|
865
|
-
} catch (err) {
|
|
866
|
-
reportError("install.flagPersist", err);
|
|
867
|
-
}
|
|
868
|
-
if (secureStore) {
|
|
869
|
-
try {
|
|
870
|
-
await secureStore.setItemAsync(INSTALL_SENT_KEY, "1");
|
|
871
|
-
} catch (err) {
|
|
872
|
-
reportError("install.flagPersistSecure", err);
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
}
|
|
402
|
+
var platform = getPlatformOS;
|
|
876
403
|
export {
|
|
877
404
|
Advenue,
|
|
878
|
-
applyAppState,
|
|
879
|
-
collectDeviceInfo,
|
|
880
|
-
createMMKVStorage,
|
|
881
|
-
createSecureStore,
|
|
882
405
|
getAndroidNative,
|
|
883
406
|
getIosNative,
|
|
884
407
|
parseDirectLink,
|
|
885
|
-
|
|
886
|
-
resolveDmaConsent,
|
|
887
|
-
trackInstall
|
|
408
|
+
platform
|
|
888
409
|
};
|