@v-tilt/browser 1.0.5 → 1.0.7

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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/dist/array.js +1 -1
  3. package/dist/array.js.map +1 -1
  4. package/dist/array.no-external.js +1 -1
  5. package/dist/array.no-external.js.map +1 -1
  6. package/dist/constants.d.ts +2 -0
  7. package/dist/extensions/history-autocapture.d.ts +19 -0
  8. package/dist/main.js +1 -1
  9. package/dist/main.js.map +1 -1
  10. package/dist/module.d.ts +192 -18
  11. package/dist/module.js +1 -1
  12. package/dist/module.js.map +1 -1
  13. package/dist/module.no-external.d.ts +192 -18
  14. package/dist/module.no-external.js +1 -1
  15. package/dist/module.no-external.js.map +1 -1
  16. package/dist/session.d.ts +61 -4
  17. package/dist/tracking.d.ts +12 -4
  18. package/dist/types.d.ts +1 -1
  19. package/dist/utils/event-utils.d.ts +35 -0
  20. package/dist/utils/patch.d.ts +8 -0
  21. package/dist/utils/user-agent-utils.d.ts +18 -0
  22. package/dist/vtilt.d.ts +58 -20
  23. package/lib/constants.d.ts +2 -0
  24. package/lib/constants.js +3 -1
  25. package/lib/extensions/history-autocapture.d.ts +19 -0
  26. package/lib/extensions/history-autocapture.js +107 -0
  27. package/lib/session.d.ts +61 -4
  28. package/lib/session.js +197 -41
  29. package/lib/tracking.d.ts +12 -4
  30. package/lib/tracking.js +65 -70
  31. package/lib/types.d.ts +1 -1
  32. package/lib/utils/event-utils.d.ts +35 -0
  33. package/lib/utils/event-utils.js +178 -0
  34. package/lib/utils/patch.d.ts +8 -0
  35. package/lib/utils/patch.js +44 -0
  36. package/lib/utils/user-agent-utils.d.ts +18 -0
  37. package/lib/utils/user-agent-utils.js +423 -0
  38. package/lib/vtilt.d.ts +58 -20
  39. package/lib/vtilt.js +168 -142
  40. package/package.json +12 -13
  41. package/dist/utils.d.ts +0 -21
  42. package/lib/utils.d.ts +0 -21
  43. package/lib/utils.js +0 -57
package/lib/vtilt.js CHANGED
@@ -6,31 +6,104 @@ exports.init_from_snippet = init_from_snippet;
6
6
  const config_1 = require("./config");
7
7
  const tracking_1 = require("./tracking");
8
8
  const web_vitals_1 = require("./web-vitals");
9
+ const history_autocapture_1 = require("./extensions/history-autocapture");
9
10
  const utils_1 = require("./utils");
10
11
  const globals_1 = require("./utils/globals");
11
12
  // Helper to check if value is an array
12
13
  const isArray = Array.isArray;
13
14
  class VTilt {
14
15
  constructor(config = {}) {
15
- this.initialized = false;
16
+ this.__loaded = false; // Matches snippet's window.vt.__loaded check
17
+ this._initialPageviewCaptured = false;
18
+ this._visibilityStateListener = null;
16
19
  this.configManager = new config_1.ConfigManager(config);
17
20
  this.trackingManager = new tracking_1.TrackingManager(this.configManager.getConfig());
18
21
  this.webVitalsManager = new web_vitals_1.WebVitalsManager(this.configManager.getConfig(), this.trackingManager);
19
22
  }
20
23
  /**
21
- * Initialize VTilt tracking
24
+ * Initializes a new instance of the VTilt tracking object.
25
+ *
26
+ * @remarks
27
+ * All new instances are added to the main vt object as sub properties (such as
28
+ * `vt.library_name`) and also returned by this function.
29
+ *
30
+ * @example
31
+ * ```js
32
+ * // basic initialization
33
+ * vt.init('<project_id>', {
34
+ * api_host: '<client_api_host>'
35
+ * })
36
+ * ```
37
+ *
38
+ * @example
39
+ * ```js
40
+ * // multiple instances
41
+ * vt.init('<project_id>', {}, 'project1')
42
+ * vt.init('<project_id>', {}, 'project2')
43
+ * ```
44
+ *
45
+ * @public
46
+ *
47
+ * @param projectId - Your VTilt project ID
48
+ * @param config - A dictionary of config options to override
49
+ * @param name - The name for the new VTilt instance that you want created
50
+ *
51
+ * @returns The newly initialized VTilt instance
22
52
  */
23
- init() {
24
- if (this.initialized) {
25
- return;
53
+ init(projectId, config, name) {
54
+ var _a;
55
+ if (!name || name === PRIMARY_INSTANCE_NAME) {
56
+ // This means we are initializing the primary instance (i.e. this)
57
+ return this._init(projectId, config, name);
26
58
  }
27
- // Only initialize in browser environment (not SSR)
28
- // This prevents errors when init() is called during Next.js server-side rendering
29
- if (!globals_1.window || !globals_1.document) {
30
- return;
59
+ else {
60
+ const namedVTilt = (_a = instances[name]) !== null && _a !== void 0 ? _a : new VTilt();
61
+ namedVTilt._init(projectId, config, name);
62
+ instances[name] = namedVTilt;
63
+ // Add as a property to the primary instance (this isn't type-safe but its how it was always done)
64
+ instances[PRIMARY_INSTANCE_NAME][name] = namedVTilt;
65
+ return namedVTilt;
66
+ }
67
+ }
68
+ /**
69
+ * Handles the actual initialization logic for a VTilt instance.
70
+ * This internal method should only be called by `init()`.
71
+ * Follows the PostHog convention of using a private `_init()` method for instance setup.
72
+ */
73
+ _init(projectId, config = {}, name) {
74
+ // Guard: prevent re-initialization (matches snippet's __loaded check)
75
+ if (this.__loaded) {
76
+ console.warn("vTilt: You have already initialized vTilt! Re-initializing is a no-op");
77
+ return this;
78
+ }
79
+ // Update config with projectId, token, and name (PostHog-style)
80
+ this.updateConfig({
81
+ ...config,
82
+ projectId: projectId || config.projectId,
83
+ name: name,
84
+ });
85
+ this.__loaded = true;
86
+ // Initialize history autocapture (PostHog-style)
87
+ this.historyAutocapture = new history_autocapture_1.HistoryAutocapture(this);
88
+ this.historyAutocapture.startIfEnabled();
89
+ // Capture initial pageview (with visibility check)
90
+ this._captureInitialPageview();
91
+ return this;
92
+ }
93
+ /**
94
+ * Returns a string representation of the instance name (PostHog-style)
95
+ * Used for debugging and logging
96
+ *
97
+ * @internal
98
+ */
99
+ toString() {
100
+ var _a;
101
+ const config = this.configManager.getConfig();
102
+ let name = (_a = config.name) !== null && _a !== void 0 ? _a : PRIMARY_INSTANCE_NAME;
103
+ if (name !== PRIMARY_INSTANCE_NAME) {
104
+ name = PRIMARY_INSTANCE_NAME + "." + name;
31
105
  }
32
- this.setupPageTracking();
33
- this.initialized = true;
106
+ return name;
34
107
  }
35
108
  /**
36
109
  * Track a custom event
@@ -139,85 +212,47 @@ class VTilt {
139
212
  this.trackingManager.createAlias(alias, original);
140
213
  }
141
214
  /**
142
- * Setup page tracking with history API support
215
+ * Capture initial pageview with visibility check
216
+ * Based on PostHog's _captureInitialPageview implementation
143
217
  */
144
- setupPageTracking() {
145
- // Only setup page tracking in browser environment (not SSR)
146
- if (!globals_1.window || !globals_1.document) {
218
+ _captureInitialPageview() {
219
+ if (!globals_1.document) {
147
220
  return;
148
221
  }
149
- // Track initial page load
150
- this.trackPageHit();
151
- // Track hash changes
152
- globals_1.window.addEventListener("hashchange", () => this.trackPageHit());
153
- // Track history API changes
154
- const history = globals_1.window.history;
155
- if (history.pushState) {
156
- // Store original functions WITHOUT binding - we'll use .call() with proper context
157
- const originalPushState = history.pushState;
158
- const originalReplaceState = history.replaceState;
159
- const vtiltInstance = this; // Capture VTilt instance for use in closures
160
- // Override pushState - use explicit parameters and .call() to preserve 'this' context
161
- Object.defineProperty(history, "pushState", {
162
- value: function (state, title, url) {
163
- // Call original with proper 'this' context using .call()
164
- originalPushState.call(this, state, title, url);
165
- // Use setTimeout to ensure the page navigation completes before tracking
166
- setTimeout(() => {
167
- vtiltInstance.trackPageHit();
168
- }, 0);
169
- },
170
- writable: true,
171
- configurable: true,
172
- });
173
- // Also override replaceState if it exists (Next.js uses this too)
174
- if (originalReplaceState) {
175
- Object.defineProperty(history, "replaceState", {
176
- value: function (state, title, url) {
177
- // Call original with proper 'this' context using .call()
178
- originalReplaceState.call(this, state, title, url);
179
- // Use setTimeout to ensure the page navigation completes before tracking
180
- setTimeout(() => {
181
- vtiltInstance.trackPageHit();
182
- }, 0);
183
- },
184
- writable: true,
185
- configurable: true,
186
- });
222
+ // If page is not visible, add a listener to detect when the page becomes visible
223
+ // and trigger the pageview only then
224
+ // This is useful to avoid `prerender` calls from Chrome/Wordpress/SPAs
225
+ // that are not visible to the user
226
+ if (globals_1.document.visibilityState !== "visible") {
227
+ if (!this._visibilityStateListener) {
228
+ this._visibilityStateListener = () => {
229
+ this._captureInitialPageview();
230
+ };
231
+ (0, utils_1.addEventListener)(globals_1.document, "visibilitychange", this._visibilityStateListener);
187
232
  }
188
- globals_1.window.addEventListener("popstate", () => this.trackPageHit());
189
- }
190
- // Handle visibility changes for prerendered pages
191
- this.setupVisibilityTracking();
192
- }
193
- /**
194
- * Track page hit
195
- */
196
- trackPageHit() {
197
- if ((0, utils_1.isTestEnvironment)()) {
198
233
  return;
199
234
  }
200
- this.trackingManager.trackPageHit();
201
- }
202
- /**
203
- * Setup visibility change tracking for prerendered pages
204
- */
205
- setupVisibilityTracking() {
206
- // Only setup visibility tracking in browser environment (not SSR)
207
- if (!globals_1.document) {
208
- return;
209
- }
210
- const lastPage = null;
211
- const doc = globals_1.document; // Capture document for use in callback
212
- const handleVisibilityChange = () => {
213
- if (!lastPage && doc.visibilityState === "visible") {
214
- this.trackPageHit();
235
+ // Extra check here to guarantee we only ever trigger a single initial pageview event
236
+ if (!this._initialPageviewCaptured) {
237
+ this._initialPageviewCaptured = true;
238
+ // Wait a bit for SPA routers (PostHog-style delay)
239
+ setTimeout(() => {
240
+ // Double-check we're still in browser environment (defensive check)
241
+ if (!globals_1.document || !globals_1.location) {
242
+ return;
243
+ }
244
+ // Note: $current_url, $host, $pathname, $referrer, $referring_domain, title
245
+ // are automatically added by sendEvent() for all events (title only for $pageview)
246
+ const payload = {
247
+ navigation_type: "initial_load",
248
+ };
249
+ this.trackingManager.sendEvent("$pageview", payload);
250
+ }, 300);
251
+ // After we've captured the initial pageview, we can remove the listener
252
+ if (this._visibilityStateListener) {
253
+ globals_1.document.removeEventListener("visibilitychange", this._visibilityStateListener);
254
+ this._visibilityStateListener = null;
215
255
  }
216
- };
217
- // Only track if page was prerendered and is now becoming visible
218
- // For normal page loads, trackPageHit() is already called in setupPageTracking()
219
- if (doc.visibilityState === "prerender") {
220
- doc.addEventListener("visibilitychange", handleVisibilityChange);
221
256
  }
222
257
  }
223
258
  /**
@@ -242,11 +277,11 @@ class VTilt {
242
277
  this.webVitalsManager = new web_vitals_1.WebVitalsManager(this.configManager.getConfig(), this.trackingManager);
243
278
  }
244
279
  /**
245
- * _execute_array() deals with processing any VTilt function
246
- * calls that were called before the VTilt library was loaded
280
+ * _execute_array() deals with processing any vTilt function
281
+ * calls that were called before the vTilt library was loaded
247
282
  * (and are thus stored in an array so they can be called later)
248
283
  *
249
- * Note: we fire off all the VTilt function calls BEFORE we fire off
284
+ * Note: we fire off all the vTilt function calls BEFORE we fire off
250
285
  * tracking calls. This is so identify/setUserProperties/updateConfig calls
251
286
  * can properly modify early tracking calls.
252
287
  *
@@ -265,7 +300,7 @@ class VTilt {
265
300
  this[methodName](...args);
266
301
  }
267
302
  catch (error) {
268
- console.error(`VTilt: Error executing queued call ${methodName}:`, error);
303
+ console.error(`vTilt: Error executing queued call ${methodName}:`, error);
269
304
  }
270
305
  }
271
306
  }
@@ -287,7 +322,7 @@ class VTilt {
287
322
  }
288
323
  exports.VTilt = VTilt;
289
324
  const instances = {};
290
- const PRIMARY_INSTANCE_NAME = "vTilt";
325
+ const PRIMARY_INSTANCE_NAME = "vt";
291
326
  // Browser support detection for request queuing
292
327
  // IE<10 does not support cross-origin XHR's but script tags
293
328
  // with defer won't block window.onload; ENQUEUE_REQUESTS
@@ -338,15 +373,15 @@ const add_dom_loaded_handler = function () {
338
373
  return;
339
374
  }
340
375
  // Only IE6-8 don't support `document.addEventListener` and we don't support them
341
- // so let's simply log an error stating VTilt couldn't be initialized
376
+ // so let's simply log an error stating vTilt couldn't be initialized
342
377
  // We're checking for `window` to avoid erroring out on a SSR context
343
378
  if (globals_1.window) {
344
- console.error("Browser doesn't support `document.addEventListener` so VTilt couldn't be initialized");
379
+ console.error("Browser doesn't support `document.addEventListener` so vTilt couldn't be initialized");
345
380
  }
346
381
  };
347
382
  /**
348
- * Initialize VTilt as a module (similar to PostHog's init_as_module)
349
- * Returns an uninitialized VTilt instance that the user must call init() on
383
+ * Initialize vTilt as a module (similar to PostHog's init_as_module)
384
+ * Returns an uninitialized vTilt instance that the user must call init() on
350
385
  */
351
386
  function init_as_module() {
352
387
  const vTiltMain = (instances[PRIMARY_INSTANCE_NAME] = new VTilt());
@@ -354,7 +389,7 @@ function init_as_module() {
354
389
  return vTiltMain;
355
390
  }
356
391
  /**
357
- * Initialize VTilt from snippet (similar to PostHog's init_from_snippet)
392
+ * Initialize vTilt from snippet (similar to PostHog's init_from_snippet)
358
393
  * Processes queued calls from the snippet stub and replaces it with real instance
359
394
  *
360
395
  * The snippet uses some clever tricks to allow deferred loading of array.js (this code)
@@ -384,58 +419,49 @@ function init_as_module() {
384
419
  * ]
385
420
  */
386
421
  function init_from_snippet() {
422
+ const vTiltMain = (instances[PRIMARY_INSTANCE_NAME] = new VTilt());
387
423
  const snippetVT = globals_1.assignableWindow["vt"];
388
- if (!snippetVT || !isArray(snippetVT)) {
389
- add_dom_loaded_handler();
390
- return;
391
- }
392
- // Process all init calls from the queue
393
- const initQueue = snippetVT._i;
394
- if (isArray(initQueue) && initQueue.length > 0) {
395
- (0, utils_1.each)(initQueue, function (item) {
396
- if (!item || !isArray(item)) {
397
- return;
398
- }
399
- const projectId = item[0];
400
- const config = item[1] || {};
401
- const name = item[2] || "vt";
402
- // Build init config with projectId and token
403
- const initConfig = {
404
- ...config,
405
- projectId: projectId || config.projectId,
406
- token: config.token,
407
- };
408
- // Warn if required fields are missing (but allow instance creation like PostHog)
409
- if (!initConfig.projectId || !initConfig.token) {
410
- console.warn("VTilt: init() called without required projectId or token. " +
411
- "Tracking will be disabled until these are provided via updateConfig().", {
412
- projectId: initConfig.projectId || "missing",
413
- token: initConfig.token ? "present" : "missing",
414
- });
415
- }
416
- // Create and initialize instance (even if config is incomplete)
417
- // Validation will happen in tracking methods when events are sent
418
- const instance = new VTilt(initConfig);
419
- instance.init();
420
- // Store instance
421
- instances[name] = instance;
422
- // Set as primary instance if it's the default name
423
- if (name === "vt" || name === PRIMARY_INSTANCE_NAME) {
424
- instances[PRIMARY_INSTANCE_NAME] = instance;
425
- }
426
- // Add named instance as property to primary instance (for PostHog compatibility)
427
- if (name !== PRIMARY_INSTANCE_NAME && instances[PRIMARY_INSTANCE_NAME]) {
428
- instances[PRIMARY_INSTANCE_NAME][name] = instance;
424
+ if (snippetVT) {
425
+ /**
426
+ * The snippet uses some clever tricks to allow deferred loading of array.js (this code)
427
+ *
428
+ * window.vt is an array which the queue of calls made before the lib is loaded
429
+ * It has methods attached to it to simulate the vt object so for instance
430
+ *
431
+ * window.vt.init("projectId", {token: "token", host: "host"})
432
+ * window.vt.trackEvent("my-event", {foo: "bar"})
433
+ *
434
+ * ... will mean that window.vt will look like this:
435
+ * window.vt == [
436
+ * ["trackEvent", "my-event", {foo: "bar"}]
437
+ * ]
438
+ *
439
+ * window.vt._i == [
440
+ * ["projectId", {token: "token", host: "host"}, "vt"]
441
+ * ]
442
+ *
443
+ * If a name is given to the init function then the same as above is true but as a sub-property on the object:
444
+ *
445
+ * window.vt.init("projectId", {token: "token"}, "vt2")
446
+ * window.vt.vt2.trackEvent("my-event", {foo: "bar"})
447
+ *
448
+ * window.vt.vt2 == [
449
+ * ["trackEvent", "my-event", {foo: "bar"}]
450
+ * ]
451
+ *
452
+ */
453
+ // Call all pre-loaded init calls properly
454
+ (0, utils_1.each)(snippetVT["_i"], function (item) {
455
+ if (item && isArray(item)) {
456
+ const instance = vTiltMain.init(item[0], item[1], item[2]);
457
+ const instanceSnippet = snippetVT[item[2] || "vt"] || snippetVT;
458
+ if (instance) {
459
+ // Execute all queued calls for this instance
460
+ instance._execute_array(instanceSnippet);
461
+ }
429
462
  }
430
- // Get the snippet queue for this instance name
431
- const instanceSnippet = snippetVT[name] || snippetVT;
432
- // Execute all queued calls for this instance
433
- instance._execute_array(instanceSnippet);
434
463
  });
435
464
  }
436
- // Replace stub with main instance (if initialized)
437
- if (instances[PRIMARY_INSTANCE_NAME] && globals_1.assignableWindow) {
438
- globals_1.assignableWindow["vt"] = instances[PRIMARY_INSTANCE_NAME];
439
- }
465
+ globals_1.assignableWindow["vt"] = vTiltMain;
440
466
  add_dom_loaded_handler();
441
467
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v-tilt/browser",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "vTilt browser tracking library",
5
5
  "main": "dist/main.js",
6
6
  "module": "dist/module.js",
@@ -12,15 +12,6 @@
12
12
  "publishConfig": {
13
13
  "access": "public"
14
14
  },
15
- "scripts": {
16
- "build": "tsc -b && rollup -c",
17
- "dev": "rollup -c -w",
18
- "type-check": "tsc --noEmit",
19
- "lint": "eslint src --ext .ts",
20
- "lint:fix": "eslint src --ext .ts --fix",
21
- "clean": "rimraf lib dist",
22
- "prepublishOnly": "pnpm run build"
23
- },
24
15
  "keywords": [
25
16
  "analytics",
26
17
  "tracking",
@@ -38,14 +29,14 @@
38
29
  "@rollup/plugin-terser": "^0.4.4",
39
30
  "@rollup/plugin-typescript": "^11.1.6",
40
31
  "@types/node": "^20.10.5",
41
- "@v-tilt/eslint-config": "workspace:*",
42
32
  "eslint": "^9.0.0",
43
33
  "rimraf": "^5.0.5",
44
34
  "rollup": "^4.9.1",
45
35
  "rollup-plugin-dts": "^6.2.3",
46
36
  "rollup-plugin-terser": "^7.0.2",
47
37
  "rollup-plugin-visualizer": "^6.0.3",
48
- "typescript": "^5.3.3"
38
+ "typescript": "^5.3.3",
39
+ "@v-tilt/eslint-config": "1.0.0"
49
40
  },
50
41
  "dependencies": {
51
42
  "web-vitals": "^3.5.0"
@@ -57,5 +48,13 @@
57
48
  "web-vitals": {
58
49
  "optional": true
59
50
  }
51
+ },
52
+ "scripts": {
53
+ "build": "tsc -b && rollup -c",
54
+ "dev": "rollup -c -w",
55
+ "type-check": "tsc --noEmit",
56
+ "lint": "eslint src --ext .ts",
57
+ "lint:fix": "eslint src --ext .ts --fix",
58
+ "clean": "rimraf lib dist"
60
59
  }
61
- }
60
+ }
package/dist/utils.d.ts DELETED
@@ -1,21 +0,0 @@
1
- import { EventPayload } from './types';
2
- /**
3
- * Generate uuid to identify the session. Random, not data-derived
4
- */
5
- export declare function uuidv4(): string;
6
- /**
7
- * Validate user agent string
8
- */
9
- export declare function isValidUserAgent(userAgent: string): boolean;
10
- /**
11
- * Validate payload string
12
- */
13
- export declare function isValidPayload(payloadStr: string): boolean;
14
- /**
15
- * Try to mask PPI and potential sensible attributes
16
- */
17
- export declare function maskSuspiciousAttributes(payload: EventPayload): string;
18
- /**
19
- * Check if current environment is a test environment
20
- */
21
- export declare function isTestEnvironment(): boolean;
package/lib/utils.d.ts DELETED
@@ -1,21 +0,0 @@
1
- import { EventPayload } from './types';
2
- /**
3
- * Generate uuid to identify the session. Random, not data-derived
4
- */
5
- export declare function uuidv4(): string;
6
- /**
7
- * Validate user agent string
8
- */
9
- export declare function isValidUserAgent(userAgent: string): boolean;
10
- /**
11
- * Validate payload string
12
- */
13
- export declare function isValidPayload(payloadStr: string): boolean;
14
- /**
15
- * Try to mask PPI and potential sensible attributes
16
- */
17
- export declare function maskSuspiciousAttributes(payload: EventPayload): string;
18
- /**
19
- * Check if current environment is a test environment
20
- */
21
- export declare function isTestEnvironment(): boolean;
package/lib/utils.js DELETED
@@ -1,57 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uuidv4 = uuidv4;
4
- exports.isValidUserAgent = isValidUserAgent;
5
- exports.isValidPayload = isValidPayload;
6
- exports.maskSuspiciousAttributes = maskSuspiciousAttributes;
7
- exports.isTestEnvironment = isTestEnvironment;
8
- const constants_1 = require("./constants");
9
- /**
10
- * Generate uuid to identify the session. Random, not data-derived
11
- */
12
- function uuidv4() {
13
- return (`${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`).replace(/[018]/g, (c) => (+c ^
14
- (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (+c / 4)))).toString(16));
15
- }
16
- /**
17
- * Validate user agent string
18
- */
19
- function isValidUserAgent(userAgent) {
20
- // empty is fine
21
- if (!userAgent || typeof userAgent !== 'string') {
22
- return true;
23
- }
24
- if (userAgent.length > 500) {
25
- return false;
26
- }
27
- return true;
28
- }
29
- /**
30
- * Validate payload string
31
- */
32
- function isValidPayload(payloadStr) {
33
- if (!payloadStr || typeof payloadStr !== 'string') {
34
- return false;
35
- }
36
- if (payloadStr.length < 2 || payloadStr.length > 10240) {
37
- return false;
38
- }
39
- return true;
40
- }
41
- /**
42
- * Try to mask PPI and potential sensible attributes
43
- */
44
- function maskSuspiciousAttributes(payload) {
45
- // Deep copy
46
- let _payload = JSON.stringify(payload);
47
- constants_1.ATTRIBUTES_TO_MASK.forEach((attr) => {
48
- _payload = _payload.replace(new RegExp(`("${attr}"):(".+?"|\\d+)`, 'gmi'), '$1:"********"');
49
- });
50
- return _payload;
51
- }
52
- /**
53
- * Check if current environment is a test environment
54
- */
55
- function isTestEnvironment() {
56
- return !!(('__nightmare' in window) || window.navigator.webdriver || ('Cypress' in window));
57
- }