@virex-tech/paywallo-sdk 2.5.3 → 2.6.2
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 +11 -0
- package/android/build.gradle +2 -1
- package/android/src/main/AndroidManifest.xml +7 -0
- package/android/src/main/java/com/paywallo/sdk/PaywalloAdvertisingIdModule.kt +55 -0
- package/android/src/main/java/com/paywallo/sdk/PaywalloSdkPackage.kt +3 -2
- package/android/src/main/java/com/paywallo/sdk/PaywalloStoreKitModule.kt +10 -3
- package/dist/index.d.mts +36 -31
- package/dist/index.d.ts +36 -31
- package/dist/index.js +352 -258
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +232 -139
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -475,7 +475,7 @@ async function readAnonIdDurably(storage) {
|
|
|
475
475
|
if (secure) return secure;
|
|
476
476
|
return nativeStorage.get(ANON_ID_FALLBACK_KEY);
|
|
477
477
|
}
|
|
478
|
-
var DEVICE_ID_KEY, ANON_ID_FALLBACK_KEY, ANON_ID_KEY, USER_EMAIL_KEY, USER_PROPERTIES_KEY, USER_DISTINCT_ID_KEY, USER_NAME_KEY, USER_COUNTRY_KEY, USER_LOCALE_KEY, USER_PHONE_KEY, USER_FIRST_NAME_KEY, USER_LAST_NAME_KEY, USER_DOB_KEY, USER_GENDER_KEY, LEGACY_USER_PHONE_KEY, LEGACY_USER_FIRST_NAME_KEY, LEGACY_USER_LAST_NAME_KEY, LEGACY_USER_DOB_KEY, LEGACY_USER_GENDER_KEY, LEGACY_DEVICE_ID_KEY, LEGACY_ANON_ID_KEY, LEGACY_EMAIL_KEY, LEGACY_PROPERTIES_KEY, LEGACY_DISTINCT_ID_KEY, LEGACY_NAME_KEY, LEGACY_COUNTRY_KEY, LEGACY_LOCALE_KEY, ANON_ID_SET_RETRIES, ANON_ID_RETRY_DELAY_MS;
|
|
478
|
+
var DEVICE_ID_KEY, ANON_ID_FALLBACK_KEY, ANON_ID_KEY, USER_EMAIL_KEY, USER_PROPERTIES_KEY, USER_DISTINCT_ID_KEY, USER_NAME_KEY, USER_COUNTRY_KEY, USER_LOCALE_KEY, USER_PHONE_KEY, USER_FIRST_NAME_KEY, USER_LAST_NAME_KEY, USER_DOB_KEY, USER_GENDER_KEY, USER_ZIP_KEY, LEGACY_USER_PHONE_KEY, LEGACY_USER_FIRST_NAME_KEY, LEGACY_USER_LAST_NAME_KEY, LEGACY_USER_DOB_KEY, LEGACY_USER_GENDER_KEY, LEGACY_DEVICE_ID_KEY, LEGACY_ANON_ID_KEY, LEGACY_EMAIL_KEY, LEGACY_PROPERTIES_KEY, LEGACY_DISTINCT_ID_KEY, LEGACY_NAME_KEY, LEGACY_COUNTRY_KEY, LEGACY_LOCALE_KEY, ANON_ID_SET_RETRIES, ANON_ID_RETRY_DELAY_MS;
|
|
479
479
|
var init_IdentityStorage = __esm({
|
|
480
480
|
"src/domains/identity/IdentityStorage.ts"() {
|
|
481
481
|
"use strict";
|
|
@@ -494,6 +494,7 @@ var init_IdentityStorage = __esm({
|
|
|
494
494
|
USER_LAST_NAME_KEY = "@paywallo:user_last_name";
|
|
495
495
|
USER_DOB_KEY = "@paywallo:user_dob";
|
|
496
496
|
USER_GENDER_KEY = "@paywallo:user_gender";
|
|
497
|
+
USER_ZIP_KEY = "@paywallo:user_zip";
|
|
497
498
|
LEGACY_USER_PHONE_KEY = "@panel:user_phone";
|
|
498
499
|
LEGACY_USER_FIRST_NAME_KEY = "@panel:user_first_name";
|
|
499
500
|
LEGACY_USER_LAST_NAME_KEY = "@panel:user_last_name";
|
|
@@ -544,6 +545,7 @@ var init_IdentityManager = __esm({
|
|
|
544
545
|
this.lastName = null;
|
|
545
546
|
this.dateOfBirth = null;
|
|
546
547
|
this.gender = null;
|
|
548
|
+
this.zipCode = null;
|
|
547
549
|
this.apiClient = null;
|
|
548
550
|
this.secureStorage = null;
|
|
549
551
|
this.debug = false;
|
|
@@ -598,7 +600,7 @@ var init_IdentityManager = __esm({
|
|
|
598
600
|
let email;
|
|
599
601
|
let properties;
|
|
600
602
|
if (options) {
|
|
601
|
-
if ("email" in options || "properties" in options || "phone" in options || "firstName" in options || "lastName" in options || "dateOfBirth" in options || "gender" in options) {
|
|
603
|
+
if ("email" in options || "properties" in options || "phone" in options || "firstName" in options || "lastName" in options || "dateOfBirth" in options || "gender" in options || "zipCode" in options) {
|
|
602
604
|
email = options.email;
|
|
603
605
|
properties = options.properties;
|
|
604
606
|
} else {
|
|
@@ -639,6 +641,10 @@ var init_IdentityManager = __esm({
|
|
|
639
641
|
this.gender = opts.gender;
|
|
640
642
|
await this.secureStorage.set(USER_GENDER_KEY, this.gender);
|
|
641
643
|
}
|
|
644
|
+
if (opts?.zipCode) {
|
|
645
|
+
this.zipCode = opts.zipCode;
|
|
646
|
+
await this.secureStorage.set(USER_ZIP_KEY, this.zipCode);
|
|
647
|
+
}
|
|
642
648
|
if (this.apiClient && this.anonId) {
|
|
643
649
|
try {
|
|
644
650
|
await this.apiClient.identify(this.anonId, properties, email, this.deviceId ?? void 0, {
|
|
@@ -646,11 +652,15 @@ var init_IdentityManager = __esm({
|
|
|
646
652
|
firstName: this.firstName ?? void 0,
|
|
647
653
|
lastName: this.lastName ?? void 0,
|
|
648
654
|
dateOfBirth: this.dateOfBirth ?? void 0,
|
|
649
|
-
gender: this.gender ?? void 0
|
|
655
|
+
gender: this.gender ?? void 0,
|
|
656
|
+
zipCode: this.zipCode ?? void 0
|
|
650
657
|
});
|
|
658
|
+
if (this.debug) console.log("[Paywallo] identify confirmed", this.anonId.slice(0, 8));
|
|
651
659
|
} catch (err) {
|
|
652
|
-
if (this.debug) console.log("[Paywallo] identify
|
|
660
|
+
if (this.debug) console.log("[Paywallo] identify failed:", err);
|
|
653
661
|
}
|
|
662
|
+
} else {
|
|
663
|
+
if (this.debug) console.log("[Paywallo] identify skipped \u2014 anonId not ready");
|
|
654
664
|
}
|
|
655
665
|
}
|
|
656
666
|
getDistinctId() {
|
|
@@ -693,6 +703,7 @@ var init_IdentityManager = __esm({
|
|
|
693
703
|
this.lastName = null;
|
|
694
704
|
this.dateOfBirth = null;
|
|
695
705
|
this.gender = null;
|
|
706
|
+
this.zipCode = null;
|
|
696
707
|
await Promise.all([
|
|
697
708
|
this.secureStorage?.set(ANON_ID_KEY, newAnonId) ?? Promise.resolve(false),
|
|
698
709
|
this.secureStorage?.remove(USER_EMAIL_KEY) ?? Promise.resolve(false),
|
|
@@ -701,7 +712,8 @@ var init_IdentityManager = __esm({
|
|
|
701
712
|
this.secureStorage?.remove(USER_FIRST_NAME_KEY) ?? Promise.resolve(false),
|
|
702
713
|
this.secureStorage?.remove(USER_LAST_NAME_KEY) ?? Promise.resolve(false),
|
|
703
714
|
this.secureStorage?.remove(USER_DOB_KEY) ?? Promise.resolve(false),
|
|
704
|
-
this.secureStorage?.remove(USER_GENDER_KEY) ?? Promise.resolve(false)
|
|
715
|
+
this.secureStorage?.remove(USER_GENDER_KEY) ?? Promise.resolve(false),
|
|
716
|
+
this.secureStorage?.remove(USER_ZIP_KEY) ?? Promise.resolve(false)
|
|
705
717
|
]);
|
|
706
718
|
}
|
|
707
719
|
getState() {
|
|
@@ -713,7 +725,8 @@ var init_IdentityManager = __esm({
|
|
|
713
725
|
firstName: this.firstName,
|
|
714
726
|
lastName: this.lastName,
|
|
715
727
|
dateOfBirth: this.dateOfBirth,
|
|
716
|
-
gender: this.gender
|
|
728
|
+
gender: this.gender,
|
|
729
|
+
zipCode: this.zipCode
|
|
717
730
|
};
|
|
718
731
|
}
|
|
719
732
|
isSecureStorageAvailable() {
|
|
@@ -931,17 +944,39 @@ var init_campaign = __esm({
|
|
|
931
944
|
}
|
|
932
945
|
});
|
|
933
946
|
|
|
947
|
+
// src/domains/identity/NativeAdvertisingId.ts
|
|
948
|
+
import { NativeModules as NativeModules2 } from "react-native";
|
|
949
|
+
var nativeModule, nativeAdvertisingId;
|
|
950
|
+
var init_NativeAdvertisingId = __esm({
|
|
951
|
+
"src/domains/identity/NativeAdvertisingId.ts"() {
|
|
952
|
+
"use strict";
|
|
953
|
+
nativeModule = NativeModules2.PaywalloAdvertisingId ?? null;
|
|
954
|
+
nativeAdvertisingId = {
|
|
955
|
+
async getAdvertisingId() {
|
|
956
|
+
try {
|
|
957
|
+
return await nativeModule?.getAdvertisingId?.() ?? null;
|
|
958
|
+
} catch {
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
});
|
|
965
|
+
|
|
934
966
|
// src/domains/identity/AdvertisingIdManager.ts
|
|
935
967
|
import { Platform as Platform2 } from "react-native";
|
|
936
|
-
var ZERO_IDFA, AdvertisingIdManager, advertisingIdManager;
|
|
968
|
+
var ZERO_IDFA, ATT_PROMPT_TIMEOUT_MS, AdvertisingIdManager, advertisingIdManager;
|
|
937
969
|
var init_AdvertisingIdManager = __esm({
|
|
938
970
|
"src/domains/identity/AdvertisingIdManager.ts"() {
|
|
939
971
|
"use strict";
|
|
940
972
|
init_NativeDeviceInfo();
|
|
973
|
+
init_NativeAdvertisingId();
|
|
941
974
|
ZERO_IDFA = "00000000-0000-0000-0000-000000000000";
|
|
975
|
+
ATT_PROMPT_TIMEOUT_MS = 4e3;
|
|
942
976
|
AdvertisingIdManager = class {
|
|
943
|
-
constructor() {
|
|
977
|
+
constructor(debug = false) {
|
|
944
978
|
this.cached = null;
|
|
979
|
+
this.debug = debug;
|
|
945
980
|
}
|
|
946
981
|
/**
|
|
947
982
|
* Synchronous accessor for the cached collect() result. Returns null until
|
|
@@ -956,6 +991,9 @@ var init_AdvertisingIdManager = __esm({
|
|
|
956
991
|
return this.cached;
|
|
957
992
|
}
|
|
958
993
|
const fallback = { idfv: null, idfa: null, gaid: null, attStatus: "unavailable" };
|
|
994
|
+
if (Platform2.OS === "android") {
|
|
995
|
+
return this.collectAndroid();
|
|
996
|
+
}
|
|
959
997
|
try {
|
|
960
998
|
const tracking = await import("expo-tracking-transparency");
|
|
961
999
|
if (Platform2.OS === "ios") {
|
|
@@ -969,9 +1007,20 @@ var init_AdvertisingIdManager = __esm({
|
|
|
969
1007
|
let status = current.status;
|
|
970
1008
|
let granted = current.granted;
|
|
971
1009
|
if (status === "undetermined" && requestATT) {
|
|
972
|
-
const result2 = await
|
|
973
|
-
|
|
974
|
-
|
|
1010
|
+
const result2 = await Promise.race([
|
|
1011
|
+
tracking.requestTrackingPermissionsAsync(),
|
|
1012
|
+
new Promise((r) => setTimeout(() => r(null), ATT_PROMPT_TIMEOUT_MS))
|
|
1013
|
+
]);
|
|
1014
|
+
if (result2 === null) {
|
|
1015
|
+
if (this.debug) {
|
|
1016
|
+
console.log(`[Paywallo] ATT prompt timed out after ${ATT_PROMPT_TIMEOUT_MS}ms \u2014 treating as undetermined`);
|
|
1017
|
+
}
|
|
1018
|
+
status = "undetermined";
|
|
1019
|
+
granted = false;
|
|
1020
|
+
} else {
|
|
1021
|
+
status = result2.status;
|
|
1022
|
+
granted = result2.granted;
|
|
1023
|
+
}
|
|
975
1024
|
}
|
|
976
1025
|
const idfv = await this.collectIdfv();
|
|
977
1026
|
const idfa = granted ? this.sanitizeId(tracking.getAdvertisingId()) : null;
|
|
@@ -979,12 +1028,6 @@ var init_AdvertisingIdManager = __esm({
|
|
|
979
1028
|
if (idfv !== null) this.cached = result;
|
|
980
1029
|
return result;
|
|
981
1030
|
}
|
|
982
|
-
if (Platform2.OS === "android") {
|
|
983
|
-
const rawGaid = tracking.getAdvertisingId();
|
|
984
|
-
const gaid = this.sanitizeId(rawGaid);
|
|
985
|
-
this.cached = { idfv: null, idfa: null, gaid, attStatus: "unavailable" };
|
|
986
|
-
return this.cached;
|
|
987
|
-
}
|
|
988
1031
|
this.cached = fallback;
|
|
989
1032
|
return this.cached;
|
|
990
1033
|
} catch {
|
|
@@ -992,6 +1035,27 @@ var init_AdvertisingIdManager = __esm({
|
|
|
992
1035
|
return this.cached;
|
|
993
1036
|
}
|
|
994
1037
|
}
|
|
1038
|
+
async collectAndroid() {
|
|
1039
|
+
const nativeGaid = this.sanitizeId(
|
|
1040
|
+
await Promise.race([
|
|
1041
|
+
nativeAdvertisingId.getAdvertisingId(),
|
|
1042
|
+
new Promise((r) => setTimeout(() => r(null), 1500))
|
|
1043
|
+
])
|
|
1044
|
+
);
|
|
1045
|
+
if (nativeGaid !== null) {
|
|
1046
|
+
this.cached = { idfv: null, idfa: null, gaid: nativeGaid, attStatus: "unavailable" };
|
|
1047
|
+
return this.cached;
|
|
1048
|
+
}
|
|
1049
|
+
try {
|
|
1050
|
+
const tracking = await import("expo-tracking-transparency");
|
|
1051
|
+
const gaid = this.sanitizeId(tracking.getAdvertisingId());
|
|
1052
|
+
this.cached = { idfv: null, idfa: null, gaid, attStatus: "unavailable" };
|
|
1053
|
+
return this.cached;
|
|
1054
|
+
} catch {
|
|
1055
|
+
this.cached = { idfv: null, idfa: null, gaid: null, attStatus: "unavailable" };
|
|
1056
|
+
return this.cached;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
995
1059
|
async collectIdfv() {
|
|
996
1060
|
const RETRY_DELAY_MS = 80;
|
|
997
1061
|
const MAX_ATTEMPTS = 3;
|
|
@@ -1598,13 +1662,13 @@ var init_deferredAppLink = __esm({
|
|
|
1598
1662
|
});
|
|
1599
1663
|
|
|
1600
1664
|
// src/domains/identity/MetaBridge.ts
|
|
1601
|
-
import { NativeModules as
|
|
1665
|
+
import { NativeModules as NativeModules3 } from "react-native";
|
|
1602
1666
|
var TIMEOUT_MS, NativeBridge, MetaBridge, metaBridge;
|
|
1603
1667
|
var init_MetaBridge = __esm({
|
|
1604
1668
|
"src/domains/identity/MetaBridge.ts"() {
|
|
1605
1669
|
"use strict";
|
|
1606
1670
|
TIMEOUT_MS = 2e3;
|
|
1607
|
-
NativeBridge =
|
|
1671
|
+
NativeBridge = NativeModules3.PaywalloFBBridge ?? null;
|
|
1608
1672
|
MetaBridge = class {
|
|
1609
1673
|
constructor() {
|
|
1610
1674
|
this.cachedAnonId = null;
|
|
@@ -1937,6 +2001,7 @@ var init_InstallTracker = __esm({
|
|
|
1937
2001
|
} else {
|
|
1938
2002
|
const { generateUUID: generateUUID2 } = await Promise.resolve().then(() => (init_uuid(), uuid_exports));
|
|
1939
2003
|
effectiveAnonId = `PW_${generateUUID2()}`;
|
|
2004
|
+
if (this.debug) console.log("[Paywallo] fb_anon_id: gerado PW_ local (Facebook Android SDK ausente no host? _fbp real indispon\xEDvel \u2014 Meta n\xE3o reconhece PW_)");
|
|
1940
2005
|
await storage.set(INSTALL_KEYS.ANON_ID, effectiveAnonId).catch(() => {
|
|
1941
2006
|
});
|
|
1942
2007
|
}
|
|
@@ -1965,11 +2030,11 @@ var init_InstallTracker = __esm({
|
|
|
1965
2030
|
...adIds.gaid && { gaid: adIds.gaid },
|
|
1966
2031
|
attStatus: adIds.attStatus
|
|
1967
2032
|
}, void 0, { priority: "critical" });
|
|
1968
|
-
void this.callDeferredMatch(apiClient, deviceData, adIds, effectiveAnonId, installedAt).catch(() => {
|
|
2033
|
+
void this.callDeferredMatch(apiClient, distinctId, deviceData, adIds, effectiveAnonId, installedAt).catch(() => {
|
|
1969
2034
|
});
|
|
1970
2035
|
await markInstallTracked(storage, installedAt);
|
|
1971
2036
|
}
|
|
1972
|
-
async callDeferredMatch(apiClient, deviceData, adIds, anonId, installedAt) {
|
|
2037
|
+
async callDeferredMatch(apiClient, distinctId, deviceData, adIds, anonId, installedAt) {
|
|
1973
2038
|
const storage = new SecureStorage(this.debug);
|
|
1974
2039
|
const alreadyMatched = await storage.get(INSTALL_KEYS.DEFERRED_MATCH_DONE);
|
|
1975
2040
|
if (alreadyMatched) return;
|
|
@@ -1984,6 +2049,10 @@ var init_InstallTracker = __esm({
|
|
|
1984
2049
|
headers: { "Content-Type": "application/json", "X-App-Key": appKey },
|
|
1985
2050
|
body: JSON.stringify({
|
|
1986
2051
|
platform: Platform4.OS,
|
|
2052
|
+
// Sem isto o servidor não tem identificador no Android (não há IDFV) e grava a
|
|
2053
|
+
// attribution com distinct_id vazio — o reader junta por
|
|
2054
|
+
// install_attributions.distinct_id = app_users.external_id e nunca casa.
|
|
2055
|
+
distinctId,
|
|
1987
2056
|
...adIds.idfv && { idfv: adIds.idfv },
|
|
1988
2057
|
...adIds.gaid && { gaid: adIds.gaid },
|
|
1989
2058
|
...referrer.rawReferrer && { installReferrer: referrer.rawReferrer },
|
|
@@ -2144,12 +2213,12 @@ var init_identity = __esm({
|
|
|
2144
2213
|
});
|
|
2145
2214
|
|
|
2146
2215
|
// src/domains/notifications/bridges/NativePushBridge.ts
|
|
2147
|
-
import { NativeEventEmitter, NativeModules as
|
|
2216
|
+
import { NativeEventEmitter, NativeModules as NativeModules4, Platform as Platform5 } from "react-native";
|
|
2148
2217
|
function getPaywalloNotifications() {
|
|
2149
|
-
return
|
|
2218
|
+
return NativeModules4.PaywalloNotifications ?? null;
|
|
2150
2219
|
}
|
|
2151
2220
|
function isNativePushAvailable() {
|
|
2152
|
-
return !!
|
|
2221
|
+
return !!NativeModules4.PaywalloNotifications;
|
|
2153
2222
|
}
|
|
2154
2223
|
function mapStatusToNumber(status) {
|
|
2155
2224
|
switch (status) {
|
|
@@ -2171,7 +2240,7 @@ function mapStatusToNumber(status) {
|
|
|
2171
2240
|
}
|
|
2172
2241
|
function getEmitter() {
|
|
2173
2242
|
if (_emitter) return _emitter;
|
|
2174
|
-
const nativeMod =
|
|
2243
|
+
const nativeMod = NativeModules4.PaywalloNotifications;
|
|
2175
2244
|
if (!nativeMod) return null;
|
|
2176
2245
|
_emitter = new NativeEventEmitter(nativeMod);
|
|
2177
2246
|
return _emitter;
|
|
@@ -2285,18 +2354,15 @@ var init_constants = __esm({
|
|
|
2285
2354
|
});
|
|
2286
2355
|
|
|
2287
2356
|
// src/domains/notifications/config.ts
|
|
2288
|
-
function resolveApiBaseUrl(
|
|
2289
|
-
if (config.apiBaseUrl) return config.apiBaseUrl;
|
|
2290
|
-
if (config.environment === "sandbox") return SANDBOX_API_BASE_URL;
|
|
2357
|
+
function resolveApiBaseUrl() {
|
|
2291
2358
|
return DEFAULT_API_BASE_URL;
|
|
2292
2359
|
}
|
|
2293
|
-
var DEFAULT_API_BASE_URL
|
|
2360
|
+
var DEFAULT_API_BASE_URL;
|
|
2294
2361
|
var init_config = __esm({
|
|
2295
2362
|
"src/domains/notifications/config.ts"() {
|
|
2296
2363
|
"use strict";
|
|
2297
2364
|
init_constants();
|
|
2298
2365
|
DEFAULT_API_BASE_URL = DEFAULT_API_URL;
|
|
2299
|
-
SANDBOX_API_BASE_URL = DEFAULT_API_URL;
|
|
2300
2366
|
}
|
|
2301
2367
|
});
|
|
2302
2368
|
|
|
@@ -2611,8 +2677,8 @@ var init_NotificationHandlerSetup = __esm({
|
|
|
2611
2677
|
// src/core/version.ts
|
|
2612
2678
|
function resolveVersion() {
|
|
2613
2679
|
try {
|
|
2614
|
-
if ("2.
|
|
2615
|
-
return "2.
|
|
2680
|
+
if ("2.6.2") {
|
|
2681
|
+
return "2.6.2";
|
|
2616
2682
|
}
|
|
2617
2683
|
} catch {
|
|
2618
2684
|
}
|
|
@@ -3066,10 +3132,7 @@ var init_NotificationsManager = __esm({
|
|
|
3066
3132
|
}
|
|
3067
3133
|
applyConfig(config) {
|
|
3068
3134
|
this.appKey = config.appKey;
|
|
3069
|
-
this.apiBaseUrl = resolveApiBaseUrl(
|
|
3070
|
-
apiBaseUrl: config.apiBaseUrl,
|
|
3071
|
-
environment: config.environment
|
|
3072
|
-
});
|
|
3135
|
+
this.apiBaseUrl = resolveApiBaseUrl();
|
|
3073
3136
|
this.debug = config.debug ?? false;
|
|
3074
3137
|
this.permissionManager.setDebug(this.debug);
|
|
3075
3138
|
}
|
|
@@ -3245,7 +3308,8 @@ var init_OnboardingError = __esm({
|
|
|
3245
3308
|
};
|
|
3246
3309
|
ONBOARDING_ERROR_CODES = {
|
|
3247
3310
|
NOT_INITIALIZED: "ONBOARDING_NOT_INITIALIZED",
|
|
3248
|
-
INVALID_STEP_NAME: "ONBOARDING_INVALID_STEP_NAME"
|
|
3311
|
+
INVALID_STEP_NAME: "ONBOARDING_INVALID_STEP_NAME",
|
|
3312
|
+
INVALID_ORDER: "ONBOARDING_INVALID_ORDER"
|
|
3249
3313
|
};
|
|
3250
3314
|
}
|
|
3251
3315
|
});
|
|
@@ -3275,16 +3339,20 @@ var init_OnboardingManager = __esm({
|
|
|
3275
3339
|
* Saves the step name internally for implicit drop detection on the backend.
|
|
3276
3340
|
*
|
|
3277
3341
|
* @param stepName - Unique name for this onboarding step.
|
|
3278
|
-
* @param order -
|
|
3342
|
+
* @param order - Ordem de exibição do step. Obrigatório. Aceita decimais (ex: 2.1 para variantes A/B).
|
|
3343
|
+
* Deve ser um número finito e não-negativo. O servidor faz o floor — não arredondar aqui.
|
|
3279
3344
|
*/
|
|
3280
|
-
async step(stepName, order) {
|
|
3345
|
+
async step(stepName, order, options) {
|
|
3281
3346
|
this.assertConfig();
|
|
3282
3347
|
this.validateStepName(stepName, "step");
|
|
3348
|
+
this.validateOrder(order);
|
|
3283
3349
|
this.lastStep = stepName;
|
|
3284
|
-
const stepPayload = {
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3350
|
+
const stepPayload = {
|
|
3351
|
+
step_name: stepName,
|
|
3352
|
+
order,
|
|
3353
|
+
...options?.variantKey !== void 0 ? { variant_key: options.variantKey } : {},
|
|
3354
|
+
...options?.timeOnPrevS !== void 0 ? { time_on_prev_s: options.timeOnPrevS } : {}
|
|
3355
|
+
};
|
|
3288
3356
|
const payload = {
|
|
3289
3357
|
family: "onboarding",
|
|
3290
3358
|
type: "step",
|
|
@@ -3296,33 +3364,21 @@ var init_OnboardingManager = __esm({
|
|
|
3296
3364
|
* Tracks successful completion of the onboarding flow.
|
|
3297
3365
|
* Marks the flow as finished.
|
|
3298
3366
|
*/
|
|
3299
|
-
async complete() {
|
|
3300
|
-
this.assertConfig();
|
|
3301
|
-
this.finished = true;
|
|
3302
|
-
return this.emit("onboarding", { family: "onboarding", type: "complete" }, "complete");
|
|
3303
|
-
}
|
|
3304
|
-
/**
|
|
3305
|
-
* Tracks an explicit drop (abandonment) at the given step.
|
|
3306
|
-
* Marks the flow as finished.
|
|
3307
|
-
*
|
|
3308
|
-
* @param stepName - The step name where the user dropped off.
|
|
3309
|
-
*/
|
|
3310
|
-
async drop(stepName) {
|
|
3367
|
+
async complete(options) {
|
|
3311
3368
|
this.assertConfig();
|
|
3312
|
-
this.validateStepName(stepName, "drop");
|
|
3313
3369
|
this.finished = true;
|
|
3314
3370
|
const payload = {
|
|
3315
3371
|
family: "onboarding",
|
|
3316
|
-
type: "
|
|
3317
|
-
...{
|
|
3372
|
+
type: "complete",
|
|
3373
|
+
...options?.variantKey !== void 0 ? { variant_key: options.variantKey } : {}
|
|
3318
3374
|
};
|
|
3319
|
-
return this.emit("onboarding", payload, "
|
|
3375
|
+
return this.emit("onboarding", payload, "complete");
|
|
3320
3376
|
}
|
|
3321
3377
|
/** Returns the last step name seen, or null if no step was tracked yet. */
|
|
3322
3378
|
getLastStep() {
|
|
3323
3379
|
return this.lastStep;
|
|
3324
3380
|
}
|
|
3325
|
-
/** Returns whether the flow has been marked as finished (complete
|
|
3381
|
+
/** Returns whether the flow has been marked as finished (complete). */
|
|
3326
3382
|
isFinished() {
|
|
3327
3383
|
return this.finished;
|
|
3328
3384
|
}
|
|
@@ -3354,6 +3410,14 @@ var init_OnboardingManager = __esm({
|
|
|
3354
3410
|
);
|
|
3355
3411
|
}
|
|
3356
3412
|
}
|
|
3413
|
+
validateOrder(order) {
|
|
3414
|
+
if (order === void 0 || order === null || !Number.isFinite(order) || order < 0) {
|
|
3415
|
+
throw new OnboardingError(
|
|
3416
|
+
ONBOARDING_ERROR_CODES.INVALID_ORDER,
|
|
3417
|
+
"OnboardingManager.step(): order deve ser um n\xFAmero finito e n\xE3o-negativo."
|
|
3418
|
+
);
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3357
3421
|
};
|
|
3358
3422
|
onboardingManager = new OnboardingManager();
|
|
3359
3423
|
}
|
|
@@ -3612,7 +3676,7 @@ var init_paywallHeartbeat = __esm({
|
|
|
3612
3676
|
});
|
|
3613
3677
|
|
|
3614
3678
|
// src/utils/localization.ts
|
|
3615
|
-
import { NativeModules as
|
|
3679
|
+
import { NativeModules as NativeModules5, Platform as Platform9 } from "react-native";
|
|
3616
3680
|
function setCurrentLanguage(language) {
|
|
3617
3681
|
currentLanguage = language;
|
|
3618
3682
|
}
|
|
@@ -3633,10 +3697,10 @@ function getLocalizedString(text) {
|
|
|
3633
3697
|
function detectDeviceLanguage() {
|
|
3634
3698
|
try {
|
|
3635
3699
|
if (Platform9.OS === "ios") {
|
|
3636
|
-
const settings =
|
|
3700
|
+
const settings = NativeModules5.SettingsManager?.settings;
|
|
3637
3701
|
return settings?.AppleLocale ?? settings?.AppleLanguages?.[0] ?? "en-US";
|
|
3638
3702
|
}
|
|
3639
|
-
return
|
|
3703
|
+
return NativeModules5.I18nManager?.localeIdentifier ?? "en-US";
|
|
3640
3704
|
} catch {
|
|
3641
3705
|
return "en-US";
|
|
3642
3706
|
}
|
|
@@ -3807,7 +3871,7 @@ import {
|
|
|
3807
3871
|
findNodeHandle,
|
|
3808
3872
|
Linking as Linking2,
|
|
3809
3873
|
NativeEventEmitter as NativeEventEmitter2,
|
|
3810
|
-
NativeModules as
|
|
3874
|
+
NativeModules as NativeModules6,
|
|
3811
3875
|
Platform as Platform10,
|
|
3812
3876
|
requireNativeComponent,
|
|
3813
3877
|
StyleSheet as StyleSheet2,
|
|
@@ -3828,7 +3892,7 @@ function getNativeWebView() {
|
|
|
3828
3892
|
}
|
|
3829
3893
|
function getWebViewEmitter() {
|
|
3830
3894
|
if (webViewEmitter) return webViewEmitter;
|
|
3831
|
-
const mod =
|
|
3895
|
+
const mod = NativeModules6.PaywalloWebViewModule;
|
|
3832
3896
|
if (!mod) return null;
|
|
3833
3897
|
webViewEmitter = new NativeEventEmitter2(mod);
|
|
3834
3898
|
return webViewEmitter;
|
|
@@ -4162,7 +4226,7 @@ __export(NativeStoreKit_exports, {
|
|
|
4162
4226
|
NativeStoreKit: () => NativeStoreKit,
|
|
4163
4227
|
nativeStoreKit: () => nativeStoreKit
|
|
4164
4228
|
});
|
|
4165
|
-
import { NativeEventEmitter as NativeEventEmitter3, NativeModules as
|
|
4229
|
+
import { NativeEventEmitter as NativeEventEmitter3, NativeModules as NativeModules7, Platform as Platform11 } from "react-native";
|
|
4166
4230
|
function isAvailable3() {
|
|
4167
4231
|
return PaywalloStoreKitNative != null;
|
|
4168
4232
|
}
|
|
@@ -4264,7 +4328,7 @@ var init_NativeStoreKit = __esm({
|
|
|
4264
4328
|
init_IdentityManager();
|
|
4265
4329
|
init_PurchaseError();
|
|
4266
4330
|
TRANSACTION_UPDATE_EVENT = "PaywalloTransactionUpdate";
|
|
4267
|
-
PaywalloStoreKitNative =
|
|
4331
|
+
PaywalloStoreKitNative = NativeModules7.PaywalloStoreKit ?? null;
|
|
4268
4332
|
nativeStoreKit = {
|
|
4269
4333
|
isAvailable: isAvailable3,
|
|
4270
4334
|
async getProducts(productIds) {
|
|
@@ -5221,7 +5285,7 @@ var init_QueueProcessor = __esm({
|
|
|
5221
5285
|
for (const item of batch) {
|
|
5222
5286
|
retryIds.add(item.id);
|
|
5223
5287
|
}
|
|
5224
|
-
console.
|
|
5288
|
+
if (this.config.debug) console.log("[Paywallo:QUEUE] event batch network error \u2014 items will retry", { size: batch.length, error: error instanceof Error ? error.message : String(error) });
|
|
5225
5289
|
this.log("Event batch threw network error - will retry", {
|
|
5226
5290
|
size: batch.length,
|
|
5227
5291
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -5234,7 +5298,7 @@ var init_QueueProcessor = __esm({
|
|
|
5234
5298
|
processed++;
|
|
5235
5299
|
}
|
|
5236
5300
|
this.log("Event batch processed successfully", { size: batch.length });
|
|
5237
|
-
} else if (response.status >= 400 && response.status < 500) {
|
|
5301
|
+
} else if (response.status >= 400 && response.status < 500 && response.status !== 429) {
|
|
5238
5302
|
for (const item of batch) {
|
|
5239
5303
|
await offlineQueue.removeItem(item.id);
|
|
5240
5304
|
failed++;
|
|
@@ -5246,7 +5310,7 @@ var init_QueueProcessor = __esm({
|
|
|
5246
5310
|
console.log("[Paywallo:QUEUE] event batch deduplicated by server \u2014 items dropped (benign)", { status: response.status, size: batch.length, error: responseError });
|
|
5247
5311
|
}
|
|
5248
5312
|
} else {
|
|
5249
|
-
console.
|
|
5313
|
+
if (this.config.debug) console.log("[Paywallo:QUEUE] event batch failed PERMANENTLY (4xx) \u2014 items dropped", { status: response.status, size: batch.length, responseBody: typeof response.data === "string" ? response.data.slice(0, 1e3) : JSON.stringify(response.data).slice(0, 1e3), firstItemBody: typeof batch[0].body === "string" ? batch[0].body.slice(0, 1e3) : JSON.stringify(batch[0].body).slice(0, 1e3) });
|
|
5250
5314
|
}
|
|
5251
5315
|
this.log("Event batch failed permanently (4xx) - removing from queue", {
|
|
5252
5316
|
status: response.status,
|
|
@@ -5257,7 +5321,7 @@ var init_QueueProcessor = __esm({
|
|
|
5257
5321
|
for (const item of batch) {
|
|
5258
5322
|
retryIds.add(item.id);
|
|
5259
5323
|
}
|
|
5260
|
-
console.
|
|
5324
|
+
if (this.config.debug) console.log("[Paywallo:QUEUE] event batch server error (5xx) \u2014 will retry", { status: response.status, size: batch.length });
|
|
5261
5325
|
this.log("Event batch failed with server error - will retry", {
|
|
5262
5326
|
status: response.status,
|
|
5263
5327
|
size: batch.length
|
|
@@ -5287,7 +5351,7 @@ var init_QueueProcessor = __esm({
|
|
|
5287
5351
|
skipRetry: false
|
|
5288
5352
|
});
|
|
5289
5353
|
} catch (error) {
|
|
5290
|
-
console.
|
|
5354
|
+
if (this.config.debug) console.log("[Paywallo:QUEUE] individual item network error \u2014 will retry", { id: item.id, url: item.url, error: error instanceof Error ? error.message : String(error) });
|
|
5291
5355
|
this.log("Request threw network error - will retry", {
|
|
5292
5356
|
id: item.id,
|
|
5293
5357
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -5298,7 +5362,7 @@ var init_QueueProcessor = __esm({
|
|
|
5298
5362
|
this.log("Queue item processed successfully", { id: item.id });
|
|
5299
5363
|
return { success: true, permanent: false };
|
|
5300
5364
|
}
|
|
5301
|
-
if (response.status >= 400 && response.status < 500) {
|
|
5365
|
+
if (response.status >= 400 && response.status < 500 && response.status !== 429) {
|
|
5302
5366
|
this.log("Request failed with permanent client error - removing from queue", {
|
|
5303
5367
|
id: item.id,
|
|
5304
5368
|
url: item.url,
|
|
@@ -6821,8 +6885,9 @@ var init_schemas = __esm({
|
|
|
6821
6885
|
path: ["transaction_id"]
|
|
6822
6886
|
});
|
|
6823
6887
|
onboardingEventSchema = z.object({
|
|
6824
|
-
type: z.enum(["step", "complete"
|
|
6825
|
-
|
|
6888
|
+
type: z.enum(["step", "complete"]),
|
|
6889
|
+
family: z.literal("onboarding").optional(),
|
|
6890
|
+
order: z.number().nonnegative().optional(),
|
|
6826
6891
|
step_name: z.string().optional(),
|
|
6827
6892
|
variant_key: z.string().optional(),
|
|
6828
6893
|
time_on_prev_s: z.number().nonnegative().optional()
|
|
@@ -6919,7 +6984,7 @@ function isValidEventName(name) {
|
|
|
6919
6984
|
async function trackEvent(apiClient, state, eventName, options) {
|
|
6920
6985
|
const distinctId = identityManager.getDistinctId();
|
|
6921
6986
|
if (!distinctId) {
|
|
6922
|
-
console.
|
|
6987
|
+
if (state.config?.debug) console.log("[Paywallo:DROP] event dropped \u2014 no distinctId available yet", { eventName });
|
|
6923
6988
|
return;
|
|
6924
6989
|
}
|
|
6925
6990
|
if (!isValidEventName(eventName)) {
|
|
@@ -7335,19 +7400,19 @@ var init_SubscriptionManager = __esm({
|
|
|
7335
7400
|
});
|
|
7336
7401
|
|
|
7337
7402
|
// src/utils/detectEnvironment.ts
|
|
7338
|
-
import { NativeModules as
|
|
7403
|
+
import { NativeModules as NativeModules8 } from "react-native";
|
|
7339
7404
|
async function detectEnvironment() {
|
|
7340
7405
|
if (cached !== null) return cached;
|
|
7341
7406
|
if (typeof globalThis.__DEV__ !== "undefined" && globalThis.__DEV__) {
|
|
7342
7407
|
cached = "sandbox";
|
|
7343
7408
|
return cached;
|
|
7344
7409
|
}
|
|
7345
|
-
if (!
|
|
7410
|
+
if (!nativeModule2) {
|
|
7346
7411
|
cached = "production";
|
|
7347
7412
|
return cached;
|
|
7348
7413
|
}
|
|
7349
7414
|
try {
|
|
7350
|
-
const result = await
|
|
7415
|
+
const result = await nativeModule2.detect();
|
|
7351
7416
|
cached = result === "sandbox" ? "sandbox" : "production";
|
|
7352
7417
|
return cached;
|
|
7353
7418
|
} catch {
|
|
@@ -7355,11 +7420,11 @@ async function detectEnvironment() {
|
|
|
7355
7420
|
return cached;
|
|
7356
7421
|
}
|
|
7357
7422
|
}
|
|
7358
|
-
var
|
|
7423
|
+
var nativeModule2, cached;
|
|
7359
7424
|
var init_detectEnvironment = __esm({
|
|
7360
7425
|
"src/utils/detectEnvironment.ts"() {
|
|
7361
7426
|
"use strict";
|
|
7362
|
-
|
|
7427
|
+
nativeModule2 = NativeModules8.PaywalloEnv ?? null;
|
|
7363
7428
|
cached = null;
|
|
7364
7429
|
}
|
|
7365
7430
|
});
|
|
@@ -7427,6 +7492,31 @@ var init_apiPurchaseMethods = __esm({
|
|
|
7427
7492
|
}
|
|
7428
7493
|
});
|
|
7429
7494
|
|
|
7495
|
+
// src/utils/userAgent.ts
|
|
7496
|
+
import { Platform as Platform14 } from "react-native";
|
|
7497
|
+
function buildUserAgent(sdkVersion) {
|
|
7498
|
+
const clean = (v) => v.replace(/[^\x20-\x7E]/g, "").replace(/[();]/g, "").trim();
|
|
7499
|
+
const info = typeof nativeDeviceInfo.getCachedDeviceInfo === "function" ? nativeDeviceInfo.getCachedDeviceInfo() : null;
|
|
7500
|
+
if (!info) {
|
|
7501
|
+
return `PaywalloSDK/${sdkVersion} (${clean(Platform14.OS)})`;
|
|
7502
|
+
}
|
|
7503
|
+
const isValid = (v) => {
|
|
7504
|
+
if (typeof v !== "string") return false;
|
|
7505
|
+
const c = clean(v);
|
|
7506
|
+
return c.length > 0 && c !== "unknown";
|
|
7507
|
+
};
|
|
7508
|
+
const parts = [clean(info.osName)];
|
|
7509
|
+
if (isValid(info.systemVersion)) parts.push(clean(info.systemVersion));
|
|
7510
|
+
const detail = isValid(info.model) ? `; ${clean(info.model)}` : "";
|
|
7511
|
+
return `PaywalloSDK/${sdkVersion} (${parts.join(" ")}${detail})`;
|
|
7512
|
+
}
|
|
7513
|
+
var init_userAgent = __esm({
|
|
7514
|
+
"src/utils/userAgent.ts"() {
|
|
7515
|
+
"use strict";
|
|
7516
|
+
init_NativeDeviceInfo();
|
|
7517
|
+
}
|
|
7518
|
+
});
|
|
7519
|
+
|
|
7430
7520
|
// src/core/ApiCache.ts
|
|
7431
7521
|
var ApiCache;
|
|
7432
7522
|
var init_ApiCache = __esm({
|
|
@@ -7654,6 +7744,11 @@ function isServerError(res) {
|
|
|
7654
7744
|
const r = res;
|
|
7655
7745
|
return r.ok === false && typeof r.status === "number" && r.status >= 500;
|
|
7656
7746
|
}
|
|
7747
|
+
function isRateLimitError(res) {
|
|
7748
|
+
if (typeof res !== "object" || res === null) return false;
|
|
7749
|
+
const r = res;
|
|
7750
|
+
return r.ok === false && r.status === 429;
|
|
7751
|
+
}
|
|
7657
7752
|
async function postWithQueue(deps, url, payload, label, priority) {
|
|
7658
7753
|
const enqueue = async () => {
|
|
7659
7754
|
await offlineQueue.enqueue(
|
|
@@ -7665,6 +7760,11 @@ async function postWithQueue(deps, url, payload, label, priority) {
|
|
|
7665
7760
|
priority
|
|
7666
7761
|
);
|
|
7667
7762
|
};
|
|
7763
|
+
if (priority === "critical" && deps.isOfflineQueueEnabled()) {
|
|
7764
|
+
await enqueue();
|
|
7765
|
+
if (deps.isDebug()) console.log("[Paywallo:ApiClient] Critical event queued (write-ahead):", label);
|
|
7766
|
+
return;
|
|
7767
|
+
}
|
|
7668
7768
|
if (deps.isOfflineQueueEnabled() && !networkMonitor.isOnline()) {
|
|
7669
7769
|
await enqueue();
|
|
7670
7770
|
if (deps.isDebug()) console.log("[Paywallo:ApiClient] Queued for offline:", label, priority ?? "normal");
|
|
@@ -7675,6 +7775,9 @@ async function postWithQueue(deps, url, payload, label, priority) {
|
|
|
7675
7775
|
if (isServerError(res) && deps.isOfflineQueueEnabled()) {
|
|
7676
7776
|
if (deps.isDebug()) console.log("[Paywallo:ApiClient] Server error, queued for retry:", label, priority ?? "normal");
|
|
7677
7777
|
await enqueue();
|
|
7778
|
+
} else if (isRateLimitError(res) && deps.isOfflineQueueEnabled()) {
|
|
7779
|
+
if (deps.isDebug()) console.log("[Paywallo:ApiClient] Rate limited (429), queued for retry:", label, priority ?? "normal");
|
|
7780
|
+
await enqueue();
|
|
7678
7781
|
}
|
|
7679
7782
|
} catch (error) {
|
|
7680
7783
|
if (deps.isDebug()) console.log("[Paywallo:ApiClient] Request failed:", label, error);
|
|
@@ -7694,7 +7797,7 @@ var init_ApiClientQueue = __esm({
|
|
|
7694
7797
|
});
|
|
7695
7798
|
|
|
7696
7799
|
// src/core/eventEnvelopeV2.ts
|
|
7697
|
-
import { Platform as
|
|
7800
|
+
import { Platform as Platform15 } from "react-native";
|
|
7698
7801
|
import { z as z2 } from "zod";
|
|
7699
7802
|
function buildV2Envelope(events, providerContext) {
|
|
7700
7803
|
const context = { ...providerContext };
|
|
@@ -7721,7 +7824,7 @@ function buildV2Envelope(events, providerContext) {
|
|
|
7721
7824
|
return { id, ts: event.timestamp, name: family, payload };
|
|
7722
7825
|
});
|
|
7723
7826
|
if (context.sdk_version === void 0) context.sdk_version = SDK_VERSION;
|
|
7724
|
-
if (context.platform === void 0) context.platform =
|
|
7827
|
+
if (context.platform === void 0) context.platform = Platform15.OS;
|
|
7725
7828
|
if (context.distinct_id === void 0 && events.length > 0) {
|
|
7726
7829
|
context.distinct_id = events[0].distinctId;
|
|
7727
7830
|
}
|
|
@@ -7859,7 +7962,7 @@ var init_events = __esm({
|
|
|
7859
7962
|
});
|
|
7860
7963
|
|
|
7861
7964
|
// src/core/EventBatcher.ts
|
|
7862
|
-
import { Platform as
|
|
7965
|
+
import { Platform as Platform16 } from "react-native";
|
|
7863
7966
|
var BATCH_MAX_SIZE, BATCH_FLUSH_MS, EVENT_NAME_REGEX, V2_BATCH_ENDPOINT, EventBatcher;
|
|
7864
7967
|
var init_EventBatcher = __esm({
|
|
7865
7968
|
"src/core/EventBatcher.ts"() {
|
|
@@ -7872,10 +7975,8 @@ var init_EventBatcher = __esm({
|
|
|
7872
7975
|
V2_BATCH_ENDPOINT = "/sdk/ingest/batch";
|
|
7873
7976
|
EventBatcher = class {
|
|
7874
7977
|
constructor(post, debug = false, contextProvider = null) {
|
|
7875
|
-
this.criticalQueue = [];
|
|
7876
7978
|
this.normalQueue = [];
|
|
7877
7979
|
this.normalTimer = null;
|
|
7878
|
-
this.criticalScheduled = false;
|
|
7879
7980
|
this.post = post;
|
|
7880
7981
|
this.debug = debug;
|
|
7881
7982
|
this.contextProvider = contextProvider;
|
|
@@ -7912,14 +8013,17 @@ var init_EventBatcher = __esm({
|
|
|
7912
8013
|
const event = {
|
|
7913
8014
|
eventName,
|
|
7914
8015
|
distinctId,
|
|
7915
|
-
properties: { ...properties, platform:
|
|
8016
|
+
properties: { ...properties, platform: Platform16.OS },
|
|
7916
8017
|
timestamp: timestamp ?? Date.now(),
|
|
7917
8018
|
environment: environment.toLowerCase()
|
|
7918
8019
|
};
|
|
7919
8020
|
const priority = options?.priority ?? "normal";
|
|
7920
8021
|
if (priority === "critical") {
|
|
7921
|
-
|
|
7922
|
-
|
|
8022
|
+
try {
|
|
8023
|
+
await this.postBatch([event], `event_critical:${event.eventName}`, "critical");
|
|
8024
|
+
} catch (err) {
|
|
8025
|
+
if (this.debug) console.log("[Paywallo:CRITICAL] critical event post failed", { eventName: event.eventName, error: err instanceof Error ? err.message : String(err) });
|
|
8026
|
+
}
|
|
7923
8027
|
return;
|
|
7924
8028
|
}
|
|
7925
8029
|
this.normalQueue.push(event);
|
|
@@ -7940,9 +8044,10 @@ var init_EventBatcher = __esm({
|
|
|
7940
8044
|
}
|
|
7941
8045
|
/**
|
|
7942
8046
|
* Force flush of the normal queue. Critical events are never held in the
|
|
7943
|
-
* normal queue, so this does not affect them
|
|
7944
|
-
*
|
|
7945
|
-
* phase 2.4) can drain pending events
|
|
8047
|
+
* normal queue, so this does not affect them — they are posted (and
|
|
8048
|
+
* awaited) synchronously inside `track()`. Exposed so callers (e.g.
|
|
8049
|
+
* `AppState=background` listener in phase 2.4) can drain pending events
|
|
8050
|
+
* before the app is suspended.
|
|
7946
8051
|
*/
|
|
7947
8052
|
async flush() {
|
|
7948
8053
|
await this.flushNormal();
|
|
@@ -7952,28 +8057,7 @@ var init_EventBatcher = __esm({
|
|
|
7952
8057
|
clearTimeout(this.normalTimer);
|
|
7953
8058
|
this.normalTimer = null;
|
|
7954
8059
|
}
|
|
7955
|
-
this.criticalQueue = [];
|
|
7956
8060
|
this.normalQueue = [];
|
|
7957
|
-
this.criticalScheduled = false;
|
|
7958
|
-
}
|
|
7959
|
-
scheduleCriticalFlush() {
|
|
7960
|
-
if (this.criticalScheduled) return;
|
|
7961
|
-
this.criticalScheduled = true;
|
|
7962
|
-
queueMicrotask(() => {
|
|
7963
|
-
this.criticalScheduled = false;
|
|
7964
|
-
void this.flushCritical();
|
|
7965
|
-
});
|
|
7966
|
-
}
|
|
7967
|
-
async flushCritical() {
|
|
7968
|
-
if (this.criticalQueue.length === 0) return;
|
|
7969
|
-
const drained = this.criticalQueue.splice(0, this.criticalQueue.length);
|
|
7970
|
-
for (const event of drained) {
|
|
7971
|
-
try {
|
|
7972
|
-
await this.postBatch([event], `event_critical:${event.eventName}`, "critical");
|
|
7973
|
-
} catch (err) {
|
|
7974
|
-
console.error("[Paywallo:CRITICAL] critical event post failed", { eventName: event.eventName, error: err instanceof Error ? err.message : String(err) });
|
|
7975
|
-
}
|
|
7976
|
-
}
|
|
7977
8061
|
}
|
|
7978
8062
|
async flushNormal() {
|
|
7979
8063
|
if (this.normalQueue.length === 0) return;
|
|
@@ -7985,7 +8069,7 @@ var init_EventBatcher = __esm({
|
|
|
7985
8069
|
try {
|
|
7986
8070
|
await this.postBatch(batch, `event_batch:${batch.length}`);
|
|
7987
8071
|
} catch (err) {
|
|
7988
|
-
console.
|
|
8072
|
+
if (this.debug) console.log("[Paywallo:NORMAL] batch post failed \u2014 relying on OfflineQueue", { batchSize: batch.length, error: err instanceof Error ? err.message : String(err) });
|
|
7989
8073
|
}
|
|
7990
8074
|
}
|
|
7991
8075
|
async postBatch(events, label, priority = "normal") {
|
|
@@ -8000,7 +8084,7 @@ var init_EventBatcher = __esm({
|
|
|
8000
8084
|
const parsed = v2EnvelopeSchema.safeParse(envelope);
|
|
8001
8085
|
if (!parsed.success) {
|
|
8002
8086
|
if (this.debug) console.log("[Paywallo EVENTS] V2 envelope schema validation failed:", parsed.error.issues);
|
|
8003
|
-
console.
|
|
8087
|
+
if (this.debug) console.log("[Paywallo:CRITICAL] V2 envelope schema validation failed", { issues: parsed.error.issues, eventCount: events.length, firstEventName: events[0]?.eventName, context: providerContext });
|
|
8004
8088
|
throw parsed.error;
|
|
8005
8089
|
}
|
|
8006
8090
|
await this.post(V2_BATCH_ENDPOINT, parsed.data, label, priority);
|
|
@@ -8238,7 +8322,7 @@ var init_http = __esm({
|
|
|
8238
8322
|
});
|
|
8239
8323
|
|
|
8240
8324
|
// src/core/ApiClient.ts
|
|
8241
|
-
import { Platform as
|
|
8325
|
+
import { Platform as Platform17 } from "react-native";
|
|
8242
8326
|
function normalizeDateOfBirth(raw) {
|
|
8243
8327
|
if (!raw) return void 0;
|
|
8244
8328
|
if (DATE_OF_BIRTH_RE.test(raw)) return raw;
|
|
@@ -8259,6 +8343,7 @@ function buildPiiPayload(pii) {
|
|
|
8259
8343
|
if (dob) result.dateOfBirth = dob;
|
|
8260
8344
|
const g = normalizeGender(pii.gender);
|
|
8261
8345
|
if (g) result.gender = g;
|
|
8346
|
+
if (pii.zipCode) result.zipCode = pii.zipCode.trim();
|
|
8262
8347
|
return result;
|
|
8263
8348
|
}
|
|
8264
8349
|
function normalizeGender(raw) {
|
|
@@ -8273,6 +8358,7 @@ var init_ApiClient = __esm({
|
|
|
8273
8358
|
"src/core/ApiClient.ts"() {
|
|
8274
8359
|
"use strict";
|
|
8275
8360
|
init_apiPurchaseMethods();
|
|
8361
|
+
init_userAgent();
|
|
8276
8362
|
init_ApiCache();
|
|
8277
8363
|
init_ApiClientFlags();
|
|
8278
8364
|
init_ApiClientQueue();
|
|
@@ -8372,10 +8458,13 @@ var init_ApiClient = __esm({
|
|
|
8372
8458
|
* should carry. Keep this tiny — it runs once per ApiClient instance.
|
|
8373
8459
|
*/
|
|
8374
8460
|
buildSdkHeaders() {
|
|
8461
|
+
const ua = buildUserAgent(SDK_VERSION);
|
|
8375
8462
|
return {
|
|
8376
8463
|
"x-sdk-version": SDK_VERSION,
|
|
8377
|
-
"x-sdk-platform":
|
|
8378
|
-
"x-sdk-environment": this.environment
|
|
8464
|
+
"x-sdk-platform": Platform17.OS,
|
|
8465
|
+
"x-sdk-environment": this.environment,
|
|
8466
|
+
"User-Agent": ua,
|
|
8467
|
+
"x-sdk-user-agent": ua
|
|
8379
8468
|
};
|
|
8380
8469
|
}
|
|
8381
8470
|
async clearQueue() {
|
|
@@ -8404,7 +8493,7 @@ var init_ApiClient = __esm({
|
|
|
8404
8493
|
message,
|
|
8405
8494
|
context,
|
|
8406
8495
|
sdkVersion: SDK_VERSION,
|
|
8407
|
-
platform:
|
|
8496
|
+
platform: Platform17.OS
|
|
8408
8497
|
}, true);
|
|
8409
8498
|
} catch (err) {
|
|
8410
8499
|
if (this.debug) console.log("[Paywallo:ApiClient] reportError failed", err);
|
|
@@ -8422,7 +8511,7 @@ var init_ApiClient = __esm({
|
|
|
8422
8511
|
async identify(distinctId, properties, email, deviceId, pii) {
|
|
8423
8512
|
const rawTraits = {
|
|
8424
8513
|
email: email || void 0,
|
|
8425
|
-
platform:
|
|
8514
|
+
platform: Platform17.OS,
|
|
8426
8515
|
name: properties?.name,
|
|
8427
8516
|
country: properties?.country,
|
|
8428
8517
|
locale: properties?.locale,
|
|
@@ -8618,7 +8707,6 @@ function setupNotifications(apiClient, config, environment, eventPipeline) {
|
|
|
8618
8707
|
notificationsManager.setupHandlers({ eventBatcher: eventPipeline });
|
|
8619
8708
|
notificationsManager.initialize({
|
|
8620
8709
|
appKey: config.appKey,
|
|
8621
|
-
apiBaseUrl: DEFAULT_API_URL,
|
|
8622
8710
|
debug: config.debug,
|
|
8623
8711
|
environment: environment === "Sandbox" ? "sandbox" : "production"
|
|
8624
8712
|
}).catch((err) => {
|
|
@@ -8660,7 +8748,6 @@ var init_PaywalloInitHelpers = __esm({
|
|
|
8660
8748
|
init_identity();
|
|
8661
8749
|
init_notifications();
|
|
8662
8750
|
init_NativePushBridge();
|
|
8663
|
-
init_constants();
|
|
8664
8751
|
init_SecureStorage();
|
|
8665
8752
|
}
|
|
8666
8753
|
});
|
|
@@ -8751,7 +8838,7 @@ function reportInitFailure(state, config, error, reason) {
|
|
|
8751
8838
|
error: error instanceof Error ? error.message : String(error)
|
|
8752
8839
|
});
|
|
8753
8840
|
} catch (err) {
|
|
8754
|
-
console.
|
|
8841
|
+
if (config.debug) console.log("[Paywallo] reportInitFailure error", err);
|
|
8755
8842
|
}
|
|
8756
8843
|
}
|
|
8757
8844
|
function reportInitSuccess(state, config, attempts) {
|
|
@@ -8760,7 +8847,7 @@ function reportInitSuccess(state, config, attempts) {
|
|
|
8760
8847
|
void state.apiClient.reportError("INIT_RECOVERED", `Succeeded after ${attempts} retries`, { attempts });
|
|
8761
8848
|
}
|
|
8762
8849
|
} catch (err) {
|
|
8763
|
-
console.
|
|
8850
|
+
if (config.debug) console.log("[Paywallo] reportInitSuccess error", err);
|
|
8764
8851
|
}
|
|
8765
8852
|
}
|
|
8766
8853
|
async function resolveSessionFlags(state, keys, apiClient, distinctId) {
|
|
@@ -8836,9 +8923,14 @@ async function doInit(state, config) {
|
|
|
8836
8923
|
} catch (err) {
|
|
8837
8924
|
if (config.debug) console.log("[Paywallo ATTR] start error", err);
|
|
8838
8925
|
}
|
|
8839
|
-
|
|
8840
|
-
|
|
8841
|
-
|
|
8926
|
+
await Promise.race([
|
|
8927
|
+
Promise.all([
|
|
8928
|
+
nativeDeviceInfo.getDeviceInfo().catch(() => null),
|
|
8929
|
+
advertisingIdManager.collect(false).catch(() => null),
|
|
8930
|
+
metaBridge.getAnonymousID().catch(() => null)
|
|
8931
|
+
]),
|
|
8932
|
+
new Promise((resolve) => setTimeout(resolve, 350))
|
|
8933
|
+
]);
|
|
8842
8934
|
apiClient.setEventContextProvider(() => {
|
|
8843
8935
|
const attr = attributionTracker.get();
|
|
8844
8936
|
const attrEntries = attr ? [
|
|
@@ -8914,12 +9006,15 @@ async function doInit(state, config) {
|
|
|
8914
9006
|
setupNotifications(apiClient, config, environment, eventPipeline);
|
|
8915
9007
|
if (config.autoStartSession !== false) {
|
|
8916
9008
|
sessionManager.startSession().catch((err) => {
|
|
8917
|
-
console.
|
|
9009
|
+
if (config.debug) console.log("[Paywallo INIT] autoStart session error", err);
|
|
8918
9010
|
});
|
|
8919
9011
|
}
|
|
8920
9012
|
new InstallTracker(config.debug, {
|
|
8921
9013
|
distinctIdProvider: () => identityManager.getDistinctId()
|
|
8922
|
-
}).trackIfNeeded(apiClient, config.requestATT === true).
|
|
9014
|
+
}).trackIfNeeded(apiClient, config.requestATT === true).then(() => {
|
|
9015
|
+
if (config.debug) console.log("[Paywallo INSTALL] $app_installed sent");
|
|
9016
|
+
}).catch(() => {
|
|
9017
|
+
if (config.debug) console.log("[Paywallo INSTALL] $app_installed failed \u2014 will retry on next launch");
|
|
8923
9018
|
});
|
|
8924
9019
|
if (config.sessionFlags && config.sessionFlags.length > 0) {
|
|
8925
9020
|
await resolveSessionFlags(state, config.sessionFlags, apiClient, distinctId);
|
|
@@ -9154,6 +9249,7 @@ var init_PaywalloClient = __esm({
|
|
|
9154
9249
|
}
|
|
9155
9250
|
if (this.state.config?.debug) console.log("[Paywallo IDENTIFY]", options ? { hasEmail: "email" in options && !!options.email, hasProperties: "properties" in options } : void 0);
|
|
9156
9251
|
await identityManager.identify(options);
|
|
9252
|
+
if (this.state.config?.debug) console.log("[Paywallo IDENTIFY] done");
|
|
9157
9253
|
}
|
|
9158
9254
|
async track(eventName, options) {
|
|
9159
9255
|
return trackEvent(this.getApiClientOrThrow(), this.state, eventName, options);
|
|
@@ -9387,9 +9483,9 @@ __export(OfferingService_exports, {
|
|
|
9387
9483
|
OfferingService: () => OfferingService,
|
|
9388
9484
|
offeringService: () => offeringService
|
|
9389
9485
|
});
|
|
9390
|
-
import { Platform as
|
|
9486
|
+
import { Platform as Platform18 } from "react-native";
|
|
9391
9487
|
function resolveProductId(raw) {
|
|
9392
|
-
const isIos =
|
|
9488
|
+
const isIos = Platform18.OS === "ios";
|
|
9393
9489
|
const productId = isIos ? raw.apple_product_id : raw.google_product_id;
|
|
9394
9490
|
return productId ?? "";
|
|
9395
9491
|
}
|
|
@@ -9408,7 +9504,7 @@ function mapProduct2(raw) {
|
|
|
9408
9504
|
};
|
|
9409
9505
|
}
|
|
9410
9506
|
function pickPlatformProduct(products) {
|
|
9411
|
-
const isIos =
|
|
9507
|
+
const isIos = Platform18.OS === "ios";
|
|
9412
9508
|
const match = products.find((p) => isIos ? p.apple_product_id : p.google_product_id);
|
|
9413
9509
|
return match ?? products[0] ?? null;
|
|
9414
9510
|
}
|
|
@@ -9635,18 +9731,14 @@ init_onboarding();
|
|
|
9635
9731
|
import { useCallback as useCallback9 } from "react";
|
|
9636
9732
|
function useOnboarding() {
|
|
9637
9733
|
const step = useCallback9(
|
|
9638
|
-
(stepName, order) => onboardingManager.step(stepName, order),
|
|
9734
|
+
(stepName, order, options) => onboardingManager.step(stepName, order, options),
|
|
9639
9735
|
[]
|
|
9640
9736
|
);
|
|
9641
9737
|
const complete = useCallback9(
|
|
9642
|
-
() => onboardingManager.complete(),
|
|
9643
|
-
[]
|
|
9644
|
-
);
|
|
9645
|
-
const drop = useCallback9(
|
|
9646
|
-
(stepName) => onboardingManager.drop(stepName),
|
|
9738
|
+
(options) => onboardingManager.complete(options),
|
|
9647
9739
|
[]
|
|
9648
9740
|
);
|
|
9649
|
-
return { step, complete
|
|
9741
|
+
return { step, complete };
|
|
9650
9742
|
}
|
|
9651
9743
|
|
|
9652
9744
|
// src/hooks/usePaywallo.ts
|
|
@@ -10960,6 +11052,7 @@ function PaywalloProvider({ children, config }) {
|
|
|
10960
11052
|
void pushAttributionToSuperwall(configRef.current.debug);
|
|
10961
11053
|
setDistinctId(PaywalloClient.getDistinctId());
|
|
10962
11054
|
setIsInitialized(true);
|
|
11055
|
+
if (configRef.current.debug) console.log("[Paywallo] SDK ready", PaywalloClient.getDistinctId()?.slice(0, 8));
|
|
10963
11056
|
if (!autoPreloadTriggeredRef.current) {
|
|
10964
11057
|
autoPreloadTriggeredRef.current = true;
|
|
10965
11058
|
const placement = await PaywalloClient.waitForAutoPreloadedPlacement();
|