@formo/analytics 1.31.0 → 1.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/FormoAnalytics.d.ts +61 -0
- package/dist/cjs/src/FormoAnalytics.js +223 -36
- package/dist/cjs/src/event/EventFactory.d.ts +21 -0
- package/dist/cjs/src/event/EventFactory.js +109 -23
- package/dist/cjs/src/event/constants.d.ts +13 -1
- package/dist/cjs/src/event/constants.js +18 -1
- package/dist/cjs/src/types/base.d.ts +28 -0
- package/dist/cjs/src/utils/index.d.ts +1 -0
- package/dist/cjs/src/utils/index.js +1 -0
- package/dist/cjs/src/utils/timezone.d.ts +7 -0
- package/dist/cjs/src/utils/timezone.js +19 -0
- package/dist/esm/src/FormoAnalytics.d.ts +61 -0
- package/dist/esm/src/FormoAnalytics.js +223 -36
- package/dist/esm/src/event/EventFactory.d.ts +21 -0
- package/dist/esm/src/event/EventFactory.js +111 -25
- package/dist/esm/src/event/constants.d.ts +13 -1
- package/dist/esm/src/event/constants.js +17 -1
- package/dist/esm/src/types/base.d.ts +28 -0
- package/dist/esm/src/utils/index.d.ts +1 -0
- package/dist/esm/src/utils/index.js +1 -0
- package/dist/esm/src/utils/timezone.d.ts +7 -0
- package/dist/esm/src/utils/timezone.js +16 -0
- package/dist/index.umd.min.js +1 -1
- package/package.json +5 -5
|
@@ -46,6 +46,15 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
46
46
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
50
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
51
|
+
if (ar || !(i in from)) {
|
|
52
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
53
|
+
ar[i] = from[i];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
57
|
+
};
|
|
49
58
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
50
59
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
51
60
|
};
|
|
@@ -67,7 +76,7 @@ var ISO_3166_ALPHA_2_REGEX = /^[A-Z]{2}$/;
|
|
|
67
76
|
var EventFactory = /** @class */ (function () {
|
|
68
77
|
function EventFactory(options) {
|
|
69
78
|
var _this = this;
|
|
70
|
-
var _a;
|
|
79
|
+
var _a, _b;
|
|
71
80
|
this.extractUTMParameters = function (url) {
|
|
72
81
|
var result = {
|
|
73
82
|
utm_campaign: "",
|
|
@@ -145,12 +154,16 @@ var EventFactory = /** @class */ (function () {
|
|
|
145
154
|
return "";
|
|
146
155
|
}
|
|
147
156
|
catch (_b) { }
|
|
148
|
-
return ref;
|
|
157
|
+
return _this.redactUrl(ref);
|
|
149
158
|
};
|
|
150
159
|
this.getTrafficSources = function (url) {
|
|
151
160
|
var urlObj = new URL(url);
|
|
152
161
|
var contextTrafficSources = __assign(__assign(__assign({}, _this.extractUTMParameters(url)), _this.extractClickIdParameters(urlObj)), { ref: _this.extractReferralParameter(urlObj), referrer: _this.getExternalReferrer() });
|
|
153
|
-
|
|
162
|
+
// Sticky traffic sources may have been persisted by an older SDK version or
|
|
163
|
+
// a looser config, before the current excludeQueryParams was in effect.
|
|
164
|
+
// Honor the current denylist on the way out so excluded values can never
|
|
165
|
+
// resurface from session storage (or get re-persisted below).
|
|
166
|
+
var storedTrafficSources = _this.redactStoredTrafficSources((0, storage_1.session)().get(constants_1.SESSION_TRAFFIC_SOURCE_KEY) || {});
|
|
154
167
|
var mergedClickIds = {};
|
|
155
168
|
for (var _i = 0, CLICK_ID_PARAMS_2 = constants_2.CLICK_ID_PARAMS; _i < CLICK_ID_PARAMS_2.length; _i++) {
|
|
156
169
|
var p = CLICK_ID_PARAMS_2[_i];
|
|
@@ -191,8 +204,17 @@ var EventFactory = /** @class */ (function () {
|
|
|
191
204
|
this.getPageProperties = function (properties) {
|
|
192
205
|
// Create a copy to avoid mutating the original properties object
|
|
193
206
|
var pageProps = __assign({}, properties);
|
|
207
|
+
// Parse the current URL once and strip any excluded (sensitive) query
|
|
208
|
+
// params up front, so nothing sensitive is forwarded via url, query, or the
|
|
209
|
+
// per-param explosion below. The hash/fragment is intentionally untouched.
|
|
210
|
+
var urlObj = null;
|
|
211
|
+
try {
|
|
212
|
+
urlObj = new URL(globalThis.location.href);
|
|
213
|
+
_this.redactQueryParams(urlObj);
|
|
214
|
+
}
|
|
215
|
+
catch (_a) { }
|
|
194
216
|
if ((0, validators_1.isUndefined)(pageProps.url)) {
|
|
195
|
-
pageProps.url =
|
|
217
|
+
pageProps.url = urlObj ? urlObj.href : globalThis.location.href;
|
|
196
218
|
}
|
|
197
219
|
if ((0, validators_1.isUndefined)(pageProps.path)) {
|
|
198
220
|
pageProps.path = globalThis.location.pathname;
|
|
@@ -202,18 +224,22 @@ var EventFactory = /** @class */ (function () {
|
|
|
202
224
|
}
|
|
203
225
|
// Add query string without the '?' prefix
|
|
204
226
|
if ((0, validators_1.isUndefined)(pageProps.query)) {
|
|
205
|
-
pageProps.query =
|
|
227
|
+
pageProps.query = urlObj
|
|
228
|
+
? urlObj.search.slice(1)
|
|
229
|
+
: globalThis.location.search.slice(1);
|
|
206
230
|
}
|
|
207
231
|
// Parse query parameters and add as individual properties (don't overwrite existing)
|
|
208
|
-
// Skip fields that are already captured in context or are semantic event properties
|
|
232
|
+
// Skip fields that are already captured in context or are semantic event properties.
|
|
233
|
+
// Excluded params were already removed from urlObj above.
|
|
209
234
|
try {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
235
|
+
if (urlObj) {
|
|
236
|
+
urlObj.searchParams.forEach(function (value, key) {
|
|
237
|
+
// Only add if the property doesn't already exist and is not excluded
|
|
238
|
+
if ((0, validators_1.isUndefined)(pageProps[key]) && !constants_2.PAGE_PROPERTIES_EXCLUDED_FIELDS.has(key)) {
|
|
239
|
+
pageProps[key] = value;
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
217
243
|
}
|
|
218
244
|
catch (error) {
|
|
219
245
|
logger_1.logger.error("Error parsing query parameters for page properties:", error);
|
|
@@ -221,8 +247,13 @@ var EventFactory = /** @class */ (function () {
|
|
|
221
247
|
return pageProps;
|
|
222
248
|
};
|
|
223
249
|
this.options = options;
|
|
250
|
+
var tracking = options === null || options === void 0 ? void 0 : options.tracking;
|
|
251
|
+
var configuredExcludes = typeof tracking === "object" ? (_a = tracking.excludeQueryParams) !== null && _a !== void 0 ? _a : [] : [];
|
|
252
|
+
this.excludedQueryParams = new Set(__spreadArray(__spreadArray([], constants_2.DEFAULT_EXCLUDED_QUERY_PARAMS, true), configuredExcludes, true).map(function (key) {
|
|
253
|
+
return key.toLowerCase();
|
|
254
|
+
}));
|
|
224
255
|
// Compile regex pattern once for better performance
|
|
225
|
-
if ((
|
|
256
|
+
if ((_b = options === null || options === void 0 ? void 0 : options.referral) === null || _b === void 0 ? void 0 : _b.pathPattern) {
|
|
226
257
|
try {
|
|
227
258
|
this.compiledPathPattern = new RegExp(options.referral.pathPattern);
|
|
228
259
|
}
|
|
@@ -245,13 +276,7 @@ var EventFactory = /** @class */ (function () {
|
|
|
245
276
|
return (0, address_1.validateAddress)(address, chainId) || null;
|
|
246
277
|
};
|
|
247
278
|
EventFactory.prototype.getTimezone = function () {
|
|
248
|
-
|
|
249
|
-
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
250
|
-
}
|
|
251
|
-
catch (error) {
|
|
252
|
-
logger_1.logger.error("Error resolving timezone:", error);
|
|
253
|
-
return "";
|
|
254
|
-
}
|
|
279
|
+
return (0, utils_1.getTimezone)();
|
|
255
280
|
};
|
|
256
281
|
EventFactory.prototype.getLocation = function () {
|
|
257
282
|
try {
|
|
@@ -284,6 +309,66 @@ var EventFactory = /** @class */ (function () {
|
|
|
284
309
|
EventFactory.prototype.getLibraryVersion = function () {
|
|
285
310
|
return version_1.version;
|
|
286
311
|
};
|
|
312
|
+
EventFactory.prototype.isExcludedQueryParam = function (key) {
|
|
313
|
+
return this.excludedQueryParams.has(key.toLowerCase());
|
|
314
|
+
};
|
|
315
|
+
/**
|
|
316
|
+
* Strip excluded (sensitive) query parameters from a URL in place. Only the
|
|
317
|
+
* query string is touched; the path and hash/fragment are left as-is.
|
|
318
|
+
*/
|
|
319
|
+
EventFactory.prototype.redactQueryParams = function (url) {
|
|
320
|
+
var _this = this;
|
|
321
|
+
// Collect first, then delete: mutating searchParams while iterating is
|
|
322
|
+
// unsafe, and deleting a key removes all of its values at once.
|
|
323
|
+
var keysToDelete = new Set();
|
|
324
|
+
url.searchParams.forEach(function (_value, key) {
|
|
325
|
+
if (_this.isExcludedQueryParam(key)) {
|
|
326
|
+
keysToDelete.add(key);
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
keysToDelete.forEach(function (key) { return url.searchParams.delete(key); });
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* Return the given absolute URL with excluded query parameters removed. The
|
|
333
|
+
* input is returned unchanged when it is empty or cannot be parsed (e.g. an
|
|
334
|
+
* empty referrer).
|
|
335
|
+
*/
|
|
336
|
+
EventFactory.prototype.redactUrl = function (href) {
|
|
337
|
+
if (!href)
|
|
338
|
+
return href;
|
|
339
|
+
try {
|
|
340
|
+
var url = new URL(href);
|
|
341
|
+
this.redactQueryParams(url);
|
|
342
|
+
return url.href;
|
|
343
|
+
}
|
|
344
|
+
catch (_a) {
|
|
345
|
+
return href;
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
/**
|
|
349
|
+
* Apply the current query-param denylist to a previously-persisted traffic
|
|
350
|
+
* source object. Traffic-source keys (utm_*, click ids, ref) are themselves
|
|
351
|
+
* query-parameter names, so an excluded key's stored value is dropped; the
|
|
352
|
+
* referrer is a URL and is re-redacted. Guards against a stored value
|
|
353
|
+
* outliving the config (or SDK version) under which it was first captured.
|
|
354
|
+
*/
|
|
355
|
+
EventFactory.prototype.redactStoredTrafficSources = function (stored) {
|
|
356
|
+
var result = {};
|
|
357
|
+
for (var _i = 0, _a = Object.keys(stored); _i < _a.length; _i++) {
|
|
358
|
+
var key = _a[_i];
|
|
359
|
+
var value = stored[key];
|
|
360
|
+
if (key === "referrer") {
|
|
361
|
+
result[key] = this.redactUrl(value || "");
|
|
362
|
+
}
|
|
363
|
+
else if (this.isExcludedQueryParam(key)) {
|
|
364
|
+
result[key] = "";
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
result[key] = value;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return result;
|
|
371
|
+
};
|
|
287
372
|
// Get screen dimensions and pixel density
|
|
288
373
|
// Returns safe defaults if any error occurs to ensure event creation continues
|
|
289
374
|
EventFactory.prototype.getScreen = function () {
|
|
@@ -312,7 +397,7 @@ var EventFactory = /** @class */ (function () {
|
|
|
312
397
|
// Contextual fields that are automatically collected and populated by the Formo SDK
|
|
313
398
|
EventFactory.prototype.generateContext = function (context) {
|
|
314
399
|
return __awaiter(this, void 0, void 0, function () {
|
|
315
|
-
var browserName, language, timezone, location, library_version, defaultContext, mergedContext;
|
|
400
|
+
var browserName, language, timezone, location, library_version, redactedHref, defaultContext, mergedContext;
|
|
316
401
|
return __generator(this, function (_a) {
|
|
317
402
|
switch (_a.label) {
|
|
318
403
|
case 0: return [4 /*yield*/, (0, browsers_1.detectBrowser)()];
|
|
@@ -322,7 +407,8 @@ var EventFactory = /** @class */ (function () {
|
|
|
322
407
|
timezone = this.getTimezone();
|
|
323
408
|
location = this.getLocation();
|
|
324
409
|
library_version = this.getLibraryVersion();
|
|
325
|
-
|
|
410
|
+
redactedHref = this.redactUrl(globalThis.location.href);
|
|
411
|
+
defaultContext = __assign(__assign(__assign({ user_agent: globalThis.navigator.userAgent, locale: language, timezone: timezone, location: location }, this.getTrafficSources(redactedHref)), { page_title: document.title, page_url: redactedHref, library_name: "Formo Web SDK", library_version: library_version, browser: browserName }), this.getScreen());
|
|
326
412
|
mergedContext = (0, mergeDeepRight_1.default)(defaultContext, context || {});
|
|
327
413
|
return [2 /*return*/, mergedContext];
|
|
328
414
|
}
|
|
@@ -6,6 +6,18 @@ declare const VERSION = "0";
|
|
|
6
6
|
* in src/types/events.ts derived from this array.
|
|
7
7
|
*/
|
|
8
8
|
declare const CLICK_ID_PARAMS: readonly ["gclid", "gad_source", "fbclid", "msclkid", "twclid", "li_fat_id", "rdt_cid", "ttclid"];
|
|
9
|
+
/**
|
|
10
|
+
* Query parameters that are ALWAYS stripped from forwarded and stored URLs,
|
|
11
|
+
* regardless of consumer configuration, because they carry high-sensitivity
|
|
12
|
+
* secrets that must never reach Formo:
|
|
13
|
+
* - privy_oauth_code: Privy OAuth authorization code
|
|
14
|
+
* - privy_oauth_state: Privy OAuth CSRF state token
|
|
15
|
+
* - privy_oauth_provider: Privy OAuth provider identifier
|
|
16
|
+
*
|
|
17
|
+
* Consumers can extend the denylist via `tracking.excludeQueryParams` but
|
|
18
|
+
* cannot remove these built-ins. Matched case-insensitively.
|
|
19
|
+
*/
|
|
20
|
+
declare const DEFAULT_EXCLUDED_QUERY_PARAMS: readonly ["privy_oauth_code", "privy_oauth_state", "privy_oauth_provider"];
|
|
9
21
|
/**
|
|
10
22
|
* Fields that should be excluded from page event properties parsing
|
|
11
23
|
* These are either:
|
|
@@ -13,5 +25,5 @@ declare const CLICK_ID_PARAMS: readonly ["gclid", "gad_source", "fbclid", "msclk
|
|
|
13
25
|
* - Semantic event properties that should not be overridden by URL params
|
|
14
26
|
*/
|
|
15
27
|
declare const PAGE_PROPERTIES_EXCLUDED_FIELDS: Set<string>;
|
|
16
|
-
export { CHANNEL, VERSION, CLICK_ID_PARAMS, PAGE_PROPERTIES_EXCLUDED_FIELDS };
|
|
28
|
+
export { CHANNEL, VERSION, CLICK_ID_PARAMS, DEFAULT_EXCLUDED_QUERY_PARAMS, PAGE_PROPERTIES_EXCLUDED_FIELDS, };
|
|
17
29
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -9,7 +9,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
9
9
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.PAGE_PROPERTIES_EXCLUDED_FIELDS = exports.CLICK_ID_PARAMS = exports.VERSION = exports.CHANNEL = void 0;
|
|
12
|
+
exports.PAGE_PROPERTIES_EXCLUDED_FIELDS = exports.DEFAULT_EXCLUDED_QUERY_PARAMS = exports.CLICK_ID_PARAMS = exports.VERSION = exports.CHANNEL = void 0;
|
|
13
13
|
var CHANNEL = "web";
|
|
14
14
|
exports.CHANNEL = CHANNEL;
|
|
15
15
|
var VERSION = "0";
|
|
@@ -30,6 +30,23 @@ var CLICK_ID_PARAMS = [
|
|
|
30
30
|
"ttclid", // TikTok Ads
|
|
31
31
|
];
|
|
32
32
|
exports.CLICK_ID_PARAMS = CLICK_ID_PARAMS;
|
|
33
|
+
/**
|
|
34
|
+
* Query parameters that are ALWAYS stripped from forwarded and stored URLs,
|
|
35
|
+
* regardless of consumer configuration, because they carry high-sensitivity
|
|
36
|
+
* secrets that must never reach Formo:
|
|
37
|
+
* - privy_oauth_code: Privy OAuth authorization code
|
|
38
|
+
* - privy_oauth_state: Privy OAuth CSRF state token
|
|
39
|
+
* - privy_oauth_provider: Privy OAuth provider identifier
|
|
40
|
+
*
|
|
41
|
+
* Consumers can extend the denylist via `tracking.excludeQueryParams` but
|
|
42
|
+
* cannot remove these built-ins. Matched case-insensitively.
|
|
43
|
+
*/
|
|
44
|
+
var DEFAULT_EXCLUDED_QUERY_PARAMS = [
|
|
45
|
+
"privy_oauth_code",
|
|
46
|
+
"privy_oauth_state",
|
|
47
|
+
"privy_oauth_provider",
|
|
48
|
+
];
|
|
49
|
+
exports.DEFAULT_EXCLUDED_QUERY_PARAMS = DEFAULT_EXCLUDED_QUERY_PARAMS;
|
|
33
50
|
/**
|
|
34
51
|
* Fields that should be excluded from page event properties parsing
|
|
35
52
|
* These are either:
|
|
@@ -72,6 +72,34 @@ export interface TrackingOptions {
|
|
|
72
72
|
excludeHosts?: string[];
|
|
73
73
|
excludePaths?: string[];
|
|
74
74
|
excludeChains?: ChainID[];
|
|
75
|
+
/**
|
|
76
|
+
* IANA timezone names to opt out of tracking entirely. When the visitor's
|
|
77
|
+
* resolved timezone (via `Intl.DateTimeFormat().resolvedOptions().timeZone`)
|
|
78
|
+
* matches one of these, no events are enqueued or sent — including `identify`
|
|
79
|
+
* and `connect`. Matched case-insensitively against the full timezone string.
|
|
80
|
+
*
|
|
81
|
+
* Note: this is client-side, timezone-derived geolocation. It is best-effort
|
|
82
|
+
* and can be bypassed (a VPN does not change the browser timezone, and users
|
|
83
|
+
* can change their OS timezone). For authoritative jurisdiction blocking, use
|
|
84
|
+
* server-side IP geolocation at your ingest endpoint instead.
|
|
85
|
+
*
|
|
86
|
+
* @example ["Europe/London", "America/New_York"]
|
|
87
|
+
*/
|
|
88
|
+
excludeTimezones?: string[];
|
|
89
|
+
/**
|
|
90
|
+
* Additional query parameter names to strip from forwarded and stored URLs,
|
|
91
|
+
* on top of a built-in always-on denylist (currently `privy_oauth_code`,
|
|
92
|
+
* `privy_oauth_state`, and `privy_oauth_provider`) that cannot be disabled.
|
|
93
|
+
* Matched case-insensitively. Excluded params are stripped from the captured
|
|
94
|
+
* page URL, query string, per-parameter page properties, and referrer before
|
|
95
|
+
* any event is sent. The URL hash/fragment is intentionally left untouched.
|
|
96
|
+
*
|
|
97
|
+
* Mirrors Mixpanel's `property_blacklist` and PostHog's `property_denylist`,
|
|
98
|
+
* scoped here to URL query parameters.
|
|
99
|
+
*
|
|
100
|
+
* @example ["token", "access_token", "email", "signature"]
|
|
101
|
+
*/
|
|
102
|
+
excludeQueryParams?: string[];
|
|
75
103
|
}
|
|
76
104
|
/**
|
|
77
105
|
* Configuration options for controlling wallet event autocapture
|
|
@@ -19,4 +19,5 @@ __exportStar(require("./base"), exports);
|
|
|
19
19
|
__exportStar(require("./converter"), exports);
|
|
20
20
|
__exportStar(require("./generate"), exports);
|
|
21
21
|
__exportStar(require("./hash"), exports);
|
|
22
|
+
__exportStar(require("./timezone"), exports);
|
|
22
23
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the current IANA timezone (e.g. "Europe/London") via the Intl API.
|
|
3
|
+
* Returns "" when the timezone cannot be resolved (e.g. Intl unavailable).
|
|
4
|
+
*/
|
|
5
|
+
declare const getTimezone: () => string;
|
|
6
|
+
export { getTimezone };
|
|
7
|
+
//# sourceMappingURL=timezone.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTimezone = void 0;
|
|
4
|
+
var logger_1 = require("../logger");
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the current IANA timezone (e.g. "Europe/London") via the Intl API.
|
|
7
|
+
* Returns "" when the timezone cannot be resolved (e.g. Intl unavailable).
|
|
8
|
+
*/
|
|
9
|
+
var getTimezone = function () {
|
|
10
|
+
try {
|
|
11
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone || "";
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
logger_1.logger.error("Error resolving timezone:", error);
|
|
15
|
+
return "";
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
exports.getTimezone = getTimezone;
|
|
19
|
+
//# sourceMappingURL=timezone.js.map
|
|
@@ -282,6 +282,59 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
282
282
|
private static installHistoryHooksOnce;
|
|
283
283
|
private trackPageHit;
|
|
284
284
|
private trackEvent;
|
|
285
|
+
/**
|
|
286
|
+
* Visitor-level tracking suppression.
|
|
287
|
+
*
|
|
288
|
+
* Returns true when the SDK must not persist any identity/session/chain
|
|
289
|
+
* state or send any events for this visitor — i.e. an explicit opt-out or a
|
|
290
|
+
* jurisdiction/timezone exclusion. Public entry points that write state
|
|
291
|
+
* before reaching the `shouldTrack()` event gate (identify/connect/detect)
|
|
292
|
+
* check this first so suppressed visitors leave no cookies or session state.
|
|
293
|
+
* @returns {boolean} True if all tracking and persistence must be suppressed
|
|
294
|
+
*/
|
|
295
|
+
private isTrackingSuppressed;
|
|
296
|
+
/**
|
|
297
|
+
* Whether the current environment is excluded from tracking — the visitor's
|
|
298
|
+
* timezone, the current hostname, or the current pathname matches a
|
|
299
|
+
* configured exclusion.
|
|
300
|
+
*
|
|
301
|
+
* Timezone is visitor/session-level (stable for the session); host/path are
|
|
302
|
+
* current-page-level and transient — if a SPA navigates to an allowed path,
|
|
303
|
+
* tracking resumes for future actions. Used as the "do not write identity or
|
|
304
|
+
* send events" gate at every entry point that would persist state before the
|
|
305
|
+
* `shouldTrack()` event gate.
|
|
306
|
+
* @returns {boolean} True if the current environment is excluded
|
|
307
|
+
*/
|
|
308
|
+
private isCurrentEnvironmentExcluded;
|
|
309
|
+
/**
|
|
310
|
+
* Whether the current hostname matches a configured `tracking.excludeHosts`
|
|
311
|
+
* entry (exact match). Current-page-level — see isCurrentEnvironmentExcluded.
|
|
312
|
+
* @returns {boolean} True if the current hostname is excluded
|
|
313
|
+
*/
|
|
314
|
+
private isHostExcluded;
|
|
315
|
+
/**
|
|
316
|
+
* Whether the current pathname matches a configured `tracking.excludePaths`
|
|
317
|
+
* entry (exact match). Current-page-level — see isCurrentEnvironmentExcluded.
|
|
318
|
+
* @returns {boolean} True if the current pathname is excluded
|
|
319
|
+
*/
|
|
320
|
+
private isPathExcluded;
|
|
321
|
+
/**
|
|
322
|
+
* Whether the current call is in a visitor-level suppression state — opt-out
|
|
323
|
+
* or excluded timezone — for which any persisted identity cookie should be
|
|
324
|
+
* actively purged (not merely skipped). Host/path exclusions are
|
|
325
|
+
* deliberately excluded here: they are transient current-page states, so a
|
|
326
|
+
* cookie legitimately written on an allowed page must survive a visit to an
|
|
327
|
+
* excluded route.
|
|
328
|
+
* @returns {boolean} True if persisted identity must be purged
|
|
329
|
+
*/
|
|
330
|
+
private isPersistedIdentityPurgeRequired;
|
|
331
|
+
/**
|
|
332
|
+
* Whether the visitor's browser-resolved timezone matches a configured
|
|
333
|
+
* `tracking.excludeTimezones` entry (case-insensitive). Client-side and
|
|
334
|
+
* best-effort — see TrackingOptions.excludeTimezones.
|
|
335
|
+
* @returns {boolean} True if the current timezone is excluded
|
|
336
|
+
*/
|
|
337
|
+
private isTimezoneExcluded;
|
|
285
338
|
/**
|
|
286
339
|
* Determines if tracking should be enabled based on configuration and consent
|
|
287
340
|
* @returns {boolean} True if tracking should be enabled
|
|
@@ -329,6 +382,14 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
329
382
|
* value in the normal way; existing connections are never clobbered.
|
|
330
383
|
*/
|
|
331
384
|
private backfillActiveWallet;
|
|
385
|
+
/**
|
|
386
|
+
* Apply an EVM autocapture connect/switch while tracking is suppressed
|
|
387
|
+
* (opt-out / timezone / excluded host or path): never LEARN the wallet, but
|
|
388
|
+
* if it is a switch away from an already-learned EVM wallet, drop the stale
|
|
389
|
+
* one (which also clears the active-wallet cookie) so it can't attach to a
|
|
390
|
+
* later allowed-page event.
|
|
391
|
+
*/
|
|
392
|
+
private clearStaleEvmWalletOnSwitchWhileSuppressed;
|
|
332
393
|
/**
|
|
333
394
|
* Polls for transaction receipt and emits tx.status = CONFIRMED or REVERTED.
|
|
334
395
|
*/
|