@v-tilt/browser 1.0.10 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Request utilities
3
+ * Functions for parsing URLs, query parameters, and masking sensitive data
4
+ */
5
+ /**
6
+ * Convert string URL to HTMLAnchorElement for parsing
7
+ * IE11 doesn't support `new URL`, so we use anchor element
8
+ */
9
+ export declare function convertToURL(url: string): HTMLAnchorElement | null;
10
+ /**
11
+ * Get query parameter from URL
12
+ */
13
+ export declare function getQueryParam(url: string, param: string): string;
14
+ /**
15
+ * Mask query parameters in URL
16
+ */
17
+ export declare function maskQueryParams<T extends string | undefined>(url: T, maskedParams: string[] | undefined, mask: string): T extends string ? string : undefined;
package/dist/vtilt.d.ts CHANGED
@@ -86,7 +86,8 @@ export declare class VTilt {
86
86
  /**
87
87
  * Capture an event
88
88
  * Automatically adds common properties to all events
89
- * ($current_url, $host, $pathname, $referrer, $referring_domain, $browser_language, etc.)
89
+ * ($current_url, $host, $pathname, $referrer, $referring_domain, $browser, $os, $device, $timezone, etc.)
90
+ * Only properties in EVENT_TO_PERSON_PROPERTIES are copied to person properties
90
91
  * Also adds title property for $pageview events only
91
92
  *
92
93
  * @param name - Event name
@@ -7,5 +7,6 @@ export declare const DISTINCT_ID_KEY = "vt_distinct_id";
7
7
  export declare const DEVICE_ID_KEY = "vt_device_id";
8
8
  export declare const USER_PROPERTIES_KEY = "vt_user_properties";
9
9
  export declare const USER_STATE_KEY = "vt_user_state";
10
+ export declare const INITIAL_PERSON_INFO = "$initial_person_info";
10
11
  export declare const STORAGE_METHODS: StorageMethods;
11
12
  export declare const TIMEZONES: Record<string, string>;
package/lib/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TIMEZONES = exports.STORAGE_METHODS = exports.USER_STATE_KEY = exports.USER_PROPERTIES_KEY = exports.DEVICE_ID_KEY = exports.DISTINCT_ID_KEY = exports.ANONYMOUS_ID_KEY = exports.PRIMARY_WINDOW_EXISTS_KEY = exports.WINDOW_ID_KEY = exports.STORAGE_KEY = void 0;
3
+ exports.TIMEZONES = exports.STORAGE_METHODS = exports.INITIAL_PERSON_INFO = exports.USER_STATE_KEY = exports.USER_PROPERTIES_KEY = exports.DEVICE_ID_KEY = exports.DISTINCT_ID_KEY = exports.ANONYMOUS_ID_KEY = exports.PRIMARY_WINDOW_EXISTS_KEY = exports.WINDOW_ID_KEY = exports.STORAGE_KEY = void 0;
4
4
  exports.STORAGE_KEY = "vt_session_id";
5
5
  exports.WINDOW_ID_KEY = "vt_window_id";
6
6
  exports.PRIMARY_WINDOW_EXISTS_KEY = "vt_primary_window_exists";
@@ -9,6 +9,7 @@ exports.DISTINCT_ID_KEY = "vt_distinct_id";
9
9
  exports.DEVICE_ID_KEY = "vt_device_id";
10
10
  exports.USER_PROPERTIES_KEY = "vt_user_properties";
11
11
  exports.USER_STATE_KEY = "vt_user_state";
12
+ exports.INITIAL_PERSON_INFO = "$initial_person_info";
12
13
  exports.STORAGE_METHODS = {
13
14
  cookie: "cookie",
14
15
  localStorage: "localStorage",
@@ -159,4 +159,25 @@ export declare class UserManager {
159
159
  * Remove cookie value
160
160
  */
161
161
  private removeCookieValue;
162
+ /**
163
+ * Register a value once (only if not already set)
164
+ * Stores properties in localStorage only if they don't already exist
165
+ */
166
+ private register_once;
167
+ /**
168
+ * Set initial person info
169
+ * Stores referrer and URL info on first visit for generating $initial_* properties
170
+ */
171
+ set_initial_person_info(maskPersonalDataProperties?: boolean, customPersonalDataProperties?: string[]): void;
172
+ /**
173
+ * Get initial props
174
+ * Generates $initial_* properties from stored initial person info
175
+ * These are sent with events as $set_once to preserve first values
176
+ */
177
+ get_initial_props(): Record<string, any>;
178
+ /**
179
+ * Update referrer info
180
+ * Stores current referrer information if not already stored
181
+ */
182
+ update_referrer_info(): void;
162
183
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UserManager = void 0;
4
4
  const constants_1 = require("./constants");
5
5
  const utils_1 = require("./utils");
6
+ const event_utils_1 = require("./utils/event-utils");
6
7
  class UserManager {
7
8
  constructor(storageMethod = "localStorage", domain) {
8
9
  this._cachedPersonProperties = null; // Cache for deduplication
@@ -570,5 +571,70 @@ class UserManager {
570
571
  }
571
572
  document.cookie = cookieValue;
572
573
  }
574
+ /**
575
+ * Register a value once (only if not already set)
576
+ * Stores properties in localStorage only if they don't already exist
577
+ */
578
+ register_once(props, defaultValues) {
579
+ const stored = this.getStoredUserProperties();
580
+ let changed = false;
581
+ for (const key in props) {
582
+ if (Object.prototype.hasOwnProperty.call(props, key)) {
583
+ if (!(key in stored)) {
584
+ stored[key] = props[key];
585
+ changed = true;
586
+ }
587
+ }
588
+ }
589
+ if (defaultValues) {
590
+ for (const key in defaultValues) {
591
+ if (Object.prototype.hasOwnProperty.call(defaultValues, key)) {
592
+ if (!(key in stored)) {
593
+ stored[key] = defaultValues[key];
594
+ changed = true;
595
+ }
596
+ }
597
+ }
598
+ }
599
+ if (changed) {
600
+ this.setStoredUserProperties(stored);
601
+ }
602
+ }
603
+ /**
604
+ * Set initial person info
605
+ * Stores referrer and URL info on first visit for generating $initial_* properties
606
+ */
607
+ set_initial_person_info(maskPersonalDataProperties, customPersonalDataProperties) {
608
+ const stored = this.getStoredUserProperties();
609
+ // Check if already set (backwards compatibility check)
610
+ if (stored[constants_1.INITIAL_PERSON_INFO]) {
611
+ return;
612
+ }
613
+ const personInfo = (0, event_utils_1.getPersonInfo)(maskPersonalDataProperties, customPersonalDataProperties);
614
+ this.register_once({
615
+ [constants_1.INITIAL_PERSON_INFO]: personInfo,
616
+ }, undefined);
617
+ }
618
+ /**
619
+ * Get initial props
620
+ * Generates $initial_* properties from stored initial person info
621
+ * These are sent with events as $set_once to preserve first values
622
+ */
623
+ get_initial_props() {
624
+ const stored = this.getStoredUserProperties();
625
+ const initialPersonInfo = stored[constants_1.INITIAL_PERSON_INFO];
626
+ if (!initialPersonInfo) {
627
+ return {};
628
+ }
629
+ return (0, event_utils_1.getInitialPersonPropsFromInfo)(initialPersonInfo);
630
+ }
631
+ /**
632
+ * Update referrer info
633
+ * Stores current referrer information if not already stored
634
+ */
635
+ update_referrer_info() {
636
+ const referrerInfo = (0, event_utils_1.getReferrerInfo)();
637
+ this.register_once(referrerInfo, undefined);
638
+ }
573
639
  }
574
640
  exports.UserManager = UserManager;
@@ -1,34 +1,52 @@
1
1
  /**
2
- * Get browser language
3
- * Returns the browser's language setting (e.g., "en-US")
2
+ * Event utilities
3
+ * Functions for extracting event properties, campaign parameters, and person info
4
4
  */
5
- export declare function getBrowserLanguage(): string | undefined;
5
+ export declare const PERSONAL_DATA_CAMPAIGN_PARAMS: string[];
6
+ export declare const CAMPAIGN_PARAMS: string[];
7
+ export declare const EVENT_TO_PERSON_PROPERTIES: string[];
8
+ export declare const MASKED = "<masked>";
9
+ export declare const COOKIE_CAMPAIGN_PARAMS: string[];
6
10
  /**
7
- * Get browser language prefix
8
- * Returns the language code without region (e.g., "en" from "en-US")
11
+ * Get campaign parameters from URL
12
+ * Extracts UTM and other campaign tracking parameters from current page URL
13
+ * Masks personal data parameters if configured
9
14
  */
15
+ export declare function getCampaignParams(customTrackedParams?: string[], maskPersonalDataProperties?: boolean, customPersonalDataProperties?: string[] | undefined): Record<string, string>;
16
+ export declare function getSearchInfo(): Record<string, any>;
17
+ export declare function getBrowserLanguage(): string | undefined;
10
18
  export declare function getBrowserLanguagePrefix(): string | undefined;
19
+ export declare function getReferrer(): string;
20
+ export declare function getReferringDomain(): string;
11
21
  /**
12
- * Get referrer
13
- * Returns document.referrer or '$direct' if no referrer
22
+ * Get referrer information
23
+ * Returns current referrer and referring domain
14
24
  */
15
- export declare function getReferrer(): string;
25
+ export declare function getReferrerInfo(): Record<string, any>;
16
26
  /**
17
- * Get referring domain
18
- * Returns the hostname of the referrer URL or '$direct' if no referrer
27
+ * Get person info for initial storage
28
+ * Extracts referrer and URL info, masks personal data if configured
29
+ * Returns compact format (r: referrer, u: url) for storage efficiency
19
30
  */
20
- export declare function getReferringDomain(): string;
31
+ export declare function getPersonInfo(maskPersonalDataProperties?: boolean, customPersonalDataProperties?: string[]): {
32
+ r: string;
33
+ u: string | undefined;
34
+ };
21
35
  /**
22
- * Get timezone
23
- * Returns the timezone (e.g., "America/New_York")
36
+ * Convert person info to person properties
37
+ * Extracts referrer, URL, campaign params, and search info from stored person info
24
38
  */
25
- export declare function getTimezone(): string | undefined;
39
+ export declare function getPersonPropsFromInfo(info: Record<string, any>): Record<string, any>;
26
40
  /**
27
- * Get timezone offset
28
- * Returns the timezone offset in minutes
41
+ * Convert person info to initial person properties
42
+ * Generates $initial_* properties from person info (preserves first values)
29
43
  */
44
+ export declare function getInitialPersonPropsFromInfo(info: Record<string, any>): Record<string, any>;
45
+ export declare function getTimezone(): string | undefined;
30
46
  export declare function getTimezoneOffset(): number | undefined;
31
47
  /**
32
48
  * Get event properties that should be added to all events
49
+ * Returns all event context properties (browser, device, URL, etc.) plus event metadata
50
+ * Note: Only properties in EVENT_TO_PERSON_PROPERTIES are copied to person properties
33
51
  */
34
- export declare function getEventProperties(): Record<string, any>;
52
+ export declare function getEventProperties(maskPersonalDataProperties?: boolean, customPersonalDataProperties?: string[]): Record<string, any>;
@@ -1,63 +1,248 @@
1
1
  "use strict";
2
+ /**
3
+ * Event utilities
4
+ * Functions for extracting event properties, campaign parameters, and person info
5
+ */
2
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.COOKIE_CAMPAIGN_PARAMS = exports.MASKED = exports.EVENT_TO_PERSON_PROPERTIES = exports.CAMPAIGN_PARAMS = exports.PERSONAL_DATA_CAMPAIGN_PARAMS = void 0;
8
+ exports.getCampaignParams = getCampaignParams;
9
+ exports.getSearchInfo = getSearchInfo;
3
10
  exports.getBrowserLanguage = getBrowserLanguage;
4
11
  exports.getBrowserLanguagePrefix = getBrowserLanguagePrefix;
5
12
  exports.getReferrer = getReferrer;
6
13
  exports.getReferringDomain = getReferringDomain;
14
+ exports.getReferrerInfo = getReferrerInfo;
15
+ exports.getPersonInfo = getPersonInfo;
16
+ exports.getPersonPropsFromInfo = getPersonPropsFromInfo;
17
+ exports.getInitialPersonPropsFromInfo = getInitialPersonPropsFromInfo;
7
18
  exports.getTimezone = getTimezone;
8
19
  exports.getTimezoneOffset = getTimezoneOffset;
9
20
  exports.getEventProperties = getEventProperties;
21
+ const request_utils_1 = require("./request-utils");
22
+ const index_1 = require("./index");
23
+ const index_2 = require("./index");
10
24
  const globals_1 = require("./globals");
11
25
  const user_agent_utils_1 = require("./user-agent-utils");
26
+ const URL_REGEX_PREFIX = 'https?://(.*)';
12
27
  // Library version - should match package.json version
13
- const LIB_VERSION = "1.0.7"; // TODO: Auto-import from package.json
28
+ const LIB_VERSION = '1.0.7'; // TODO: Auto-import from package.json
29
+ // Campaign parameters that could be considered personal data (e.g., GDPR)
30
+ // These can be masked in URLs and properties before being sent
31
+ exports.PERSONAL_DATA_CAMPAIGN_PARAMS = [
32
+ 'gclid', // google ads
33
+ 'gclsrc', // google ads 360
34
+ 'dclid', // google display ads
35
+ 'gbraid', // google ads, web to app
36
+ 'wbraid', // google ads, app to web
37
+ 'fbclid', // facebook
38
+ 'msclkid', // microsoft
39
+ 'twclid', // twitter
40
+ 'li_fat_id', // linkedin
41
+ 'igshid', // instagram
42
+ 'ttclid', // tiktok
43
+ 'rdt_cid', // reddit
44
+ 'epik', // pinterest
45
+ 'qclid', // quora
46
+ 'sccid', // snapchat
47
+ 'irclid', // impact
48
+ '_kx', // klaviyo
49
+ ];
50
+ exports.CAMPAIGN_PARAMS = (0, index_2.extendArray)([
51
+ 'utm_source',
52
+ 'utm_medium',
53
+ 'utm_campaign',
54
+ 'utm_content',
55
+ 'utm_term',
56
+ 'gad_source', // google ads source
57
+ 'mc_cid', // mailchimp campaign id
58
+ ], exports.PERSONAL_DATA_CAMPAIGN_PARAMS);
59
+ // Properties that should be automatically copied from events to person properties
60
+ exports.EVENT_TO_PERSON_PROPERTIES = [
61
+ // Mobile app properties
62
+ '$app_build',
63
+ '$app_name',
64
+ '$app_namespace',
65
+ '$app_version',
66
+ // Web browser properties
67
+ '$browser',
68
+ '$browser_version',
69
+ '$device_type',
70
+ '$current_url',
71
+ '$pathname',
72
+ '$os',
73
+ '$os_name', // Special case: treated as alias of $os
74
+ '$os_version',
75
+ '$referring_domain',
76
+ '$referrer',
77
+ '$screen_height',
78
+ '$screen_width',
79
+ '$viewport_height',
80
+ '$viewport_width',
81
+ '$raw_user_agent',
82
+ ];
83
+ exports.MASKED = '<masked>';
84
+ // Campaign params that can be read from cookies (currently not implemented)
85
+ exports.COOKIE_CAMPAIGN_PARAMS = [
86
+ 'li_fat_id', // linkedin
87
+ ];
14
88
  /**
15
- * Get browser language
16
- * Returns the browser's language setting (e.g., "en-US")
89
+ * Get campaign parameters from URL
90
+ * Extracts UTM and other campaign tracking parameters from current page URL
91
+ * Masks personal data parameters if configured
17
92
  */
93
+ function getCampaignParams(customTrackedParams, maskPersonalDataProperties, customPersonalDataProperties) {
94
+ if (!globals_1.document) {
95
+ return {};
96
+ }
97
+ const paramsToMask = maskPersonalDataProperties
98
+ ? (0, index_2.extendArray)([], exports.PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])
99
+ : [];
100
+ // Initially get campaign params from the URL
101
+ const urlCampaignParams = _getCampaignParamsFromUrl((0, request_utils_1.maskQueryParams)(globals_1.document.URL, paramsToMask, exports.MASKED), customTrackedParams);
102
+ // But we can also get some of them from the cookie store
103
+ // For now, we'll skip cookie-based campaign params (would need cookie store implementation)
104
+ const cookieCampaignParams = {};
105
+ // Prefer the values found in the urlCampaignParams if possible
106
+ // `extend` will override the values if found in the second argument
107
+ return (0, index_2.extend)(cookieCampaignParams, urlCampaignParams);
108
+ }
109
+ function _getCampaignParamsFromUrl(url, customParams) {
110
+ const campaign_keywords = exports.CAMPAIGN_PARAMS.concat(customParams || []);
111
+ const params = {};
112
+ (0, index_2.each)(campaign_keywords, function (kwkey) {
113
+ const kw = (0, request_utils_1.getQueryParam)(url, kwkey);
114
+ params[kwkey] = kw ? kw : null;
115
+ });
116
+ return params;
117
+ }
118
+ function _getSearchEngine(referrer) {
119
+ if (!referrer) {
120
+ return null;
121
+ }
122
+ else {
123
+ if (referrer.search(URL_REGEX_PREFIX + 'google.([^/?]*)') === 0) {
124
+ return 'google';
125
+ }
126
+ else if (referrer.search(URL_REGEX_PREFIX + 'bing.com') === 0) {
127
+ return 'bing';
128
+ }
129
+ else if (referrer.search(URL_REGEX_PREFIX + 'yahoo.com') === 0) {
130
+ return 'yahoo';
131
+ }
132
+ else if (referrer.search(URL_REGEX_PREFIX + 'duckduckgo.com') === 0) {
133
+ return 'duckduckgo';
134
+ }
135
+ else {
136
+ return null;
137
+ }
138
+ }
139
+ }
140
+ function _getSearchInfoFromReferrer(referrer) {
141
+ const search = _getSearchEngine(referrer);
142
+ const param = search != 'yahoo' ? 'q' : 'p';
143
+ const ret = {};
144
+ if (!(0, index_1.isNull)(search)) {
145
+ ret['$search_engine'] = search;
146
+ const keyword = globals_1.document ? (0, request_utils_1.getQueryParam)(globals_1.document.referrer, param) : '';
147
+ if (keyword.length) {
148
+ ret['ph_keyword'] = keyword;
149
+ }
150
+ }
151
+ return ret;
152
+ }
153
+ function getSearchInfo() {
154
+ const referrer = globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.referrer;
155
+ if (!referrer) {
156
+ return {};
157
+ }
158
+ return _getSearchInfoFromReferrer(referrer);
159
+ }
18
160
  function getBrowserLanguage() {
19
- if (typeof globals_1.navigator === "undefined") {
161
+ if (typeof navigator === 'undefined') {
20
162
  return undefined;
21
163
  }
22
- return (globals_1.navigator.language || // Any modern browser
23
- globals_1.navigator.userLanguage // IE11
164
+ return (navigator.language || // Any modern browser
165
+ navigator.userLanguage // IE11
24
166
  );
25
167
  }
26
- /**
27
- * Get browser language prefix
28
- * Returns the language code without region (e.g., "en" from "en-US")
29
- */
30
168
  function getBrowserLanguagePrefix() {
31
169
  const lang = getBrowserLanguage();
32
- return typeof lang === "string" ? lang.split("-")[0] : undefined;
170
+ return typeof lang === 'string' ? lang.split('-')[0] : undefined;
33
171
  }
34
- /**
35
- * Get referrer
36
- * Returns document.referrer or '$direct' if no referrer
37
- */
38
172
  function getReferrer() {
39
- return (globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.referrer) || "$direct";
173
+ return (globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.referrer) || '$direct';
40
174
  }
41
- /**
42
- * Get referring domain
43
- * Returns the hostname of the referrer URL or '$direct' if no referrer
44
- */
45
175
  function getReferringDomain() {
176
+ var _a;
46
177
  if (!(globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.referrer)) {
47
- return "$direct";
178
+ return '$direct';
48
179
  }
49
- try {
50
- const url = new URL(globals_1.document.referrer);
51
- return url.host || "$direct";
180
+ return ((_a = (0, request_utils_1.convertToURL)(globals_1.document.referrer)) === null || _a === void 0 ? void 0 : _a.host) || '$direct';
181
+ }
182
+ /**
183
+ * Get referrer information
184
+ * Returns current referrer and referring domain
185
+ */
186
+ function getReferrerInfo() {
187
+ return {
188
+ $referrer: getReferrer(),
189
+ $referring_domain: getReferringDomain(),
190
+ };
191
+ }
192
+ /**
193
+ * Get person info for initial storage
194
+ * Extracts referrer and URL info, masks personal data if configured
195
+ * Returns compact format (r: referrer, u: url) for storage efficiency
196
+ */
197
+ function getPersonInfo(maskPersonalDataProperties, customPersonalDataProperties) {
198
+ const paramsToMask = maskPersonalDataProperties
199
+ ? (0, index_2.extendArray)([], exports.PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])
200
+ : [];
201
+ const url = globals_1.location === null || globals_1.location === void 0 ? void 0 : globals_1.location.href.substring(0, 1000);
202
+ // Compact format for storage efficiency (stored in localStorage)
203
+ return {
204
+ r: getReferrer().substring(0, 1000),
205
+ u: url ? (0, request_utils_1.maskQueryParams)(url, paramsToMask, exports.MASKED) : undefined,
206
+ };
207
+ }
208
+ /**
209
+ * Convert person info to person properties
210
+ * Extracts referrer, URL, campaign params, and search info from stored person info
211
+ */
212
+ function getPersonPropsFromInfo(info) {
213
+ var _a;
214
+ const { r: referrer, u: url } = info;
215
+ const referring_domain = referrer == null ? undefined : referrer == '$direct' ? '$direct' : (_a = (0, request_utils_1.convertToURL)(referrer)) === null || _a === void 0 ? void 0 : _a.host;
216
+ const props = {
217
+ $referrer: referrer,
218
+ $referring_domain: referring_domain,
219
+ };
220
+ if (url) {
221
+ props['$current_url'] = url;
222
+ const location = (0, request_utils_1.convertToURL)(url);
223
+ props['$host'] = location === null || location === void 0 ? void 0 : location.host;
224
+ props['$pathname'] = location === null || location === void 0 ? void 0 : location.pathname;
225
+ const campaignParams = _getCampaignParamsFromUrl(url);
226
+ (0, index_2.extend)(props, campaignParams);
52
227
  }
53
- catch (_a) {
54
- return "$direct";
228
+ if (referrer) {
229
+ const searchInfo = _getSearchInfoFromReferrer(referrer);
230
+ (0, index_2.extend)(props, searchInfo);
55
231
  }
232
+ return props;
56
233
  }
57
234
  /**
58
- * Get timezone
59
- * Returns the timezone (e.g., "America/New_York")
235
+ * Convert person info to initial person properties
236
+ * Generates $initial_* properties from person info (preserves first values)
60
237
  */
238
+ function getInitialPersonPropsFromInfo(info) {
239
+ const personProps = getPersonPropsFromInfo(info);
240
+ const props = {};
241
+ (0, index_2.each)(personProps, function (val, key) {
242
+ props[`$initial_${(0, index_1.stripLeadingDollar)(String(key))}`] = val;
243
+ });
244
+ return props;
245
+ }
61
246
  function getTimezone() {
62
247
  try {
63
248
  return Intl.DateTimeFormat().resolvedOptions().timeZone;
@@ -66,10 +251,6 @@ function getTimezone() {
66
251
  return undefined;
67
252
  }
68
253
  }
69
- /**
70
- * Get timezone offset
71
- * Returns the timezone offset in minutes
72
- */
73
254
  function getTimezoneOffset() {
74
255
  try {
75
256
  return new Date().getTimezoneOffset();
@@ -78,100 +259,42 @@ function getTimezoneOffset() {
78
259
  return undefined;
79
260
  }
80
261
  }
81
- /**
82
- * Generate insert ID for deduplication
83
- */
84
- function generateInsertId() {
85
- return (Math.random().toString(36).substring(2, 10) +
86
- Math.random().toString(36).substring(2, 10));
87
- }
88
262
  /**
89
263
  * Get event properties that should be added to all events
264
+ * Returns all event context properties (browser, device, URL, etc.) plus event metadata
265
+ * Note: Only properties in EVENT_TO_PERSON_PROPERTIES are copied to person properties
90
266
  */
91
- function getEventProperties() {
92
- const props = {};
267
+ function getEventProperties(maskPersonalDataProperties, customPersonalDataProperties) {
93
268
  if (!globals_1.userAgent) {
94
- return props;
269
+ return {};
95
270
  }
96
- // Device/OS properties
271
+ const paramsToMask = maskPersonalDataProperties
272
+ ? (0, index_2.extendArray)([], exports.PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])
273
+ : [];
97
274
  const [os_name, os_version] = (0, user_agent_utils_1.detectOS)(globals_1.userAgent);
98
- if (os_name) {
99
- props.$os = os_name;
100
- }
101
- if (os_version) {
102
- props.$os_version = os_version;
103
- }
104
- const browser = (0, user_agent_utils_1.detectBrowser)(globals_1.userAgent, globals_1.navigator === null || globals_1.navigator === void 0 ? void 0 : globals_1.navigator.vendor);
105
- if (browser) {
106
- props.$browser = browser;
107
- }
108
- const browserVersion = (0, user_agent_utils_1.detectBrowserVersion)(globals_1.userAgent, globals_1.navigator === null || globals_1.navigator === void 0 ? void 0 : globals_1.navigator.vendor);
109
- if (browserVersion) {
110
- props.$browser_version = browserVersion;
111
- }
112
- const device = (0, user_agent_utils_1.detectDevice)(globals_1.userAgent);
113
- if (device) {
114
- props.$device = device;
115
- }
116
- const deviceType = (0, user_agent_utils_1.detectDeviceType)(globals_1.userAgent);
117
- if (deviceType) {
118
- props.$device_type = deviceType;
119
- }
120
- // Timezone properties
121
- const timezone = getTimezone();
122
- if (timezone) {
123
- props.$timezone = timezone;
124
- }
125
- const timezoneOffset = getTimezoneOffset();
126
- if (timezoneOffset !== undefined) {
127
- props.$timezone_offset = timezoneOffset;
128
- }
129
- // URL properties (added to all events)
130
- if (globals_1.location) {
131
- props.$current_url = globals_1.location.href;
132
- props.$host = globals_1.location.host;
133
- props.$pathname = globals_1.location.pathname;
134
- }
135
- // User agent
136
- if (globals_1.userAgent) {
137
- props.$raw_user_agent =
138
- globals_1.userAgent.length > 1000 ? globals_1.userAgent.substring(0, 997) + "..." : globals_1.userAgent;
139
- }
140
- // Browser language (added to all events)
141
- const browserLanguage = getBrowserLanguage();
142
- const browserLanguagePrefix = getBrowserLanguagePrefix();
143
- if (browserLanguage) {
144
- props.$browser_language = browserLanguage;
145
- }
146
- if (browserLanguagePrefix) {
147
- props.$browser_language_prefix = browserLanguagePrefix;
148
- }
149
- // Screen/viewport properties
150
- if (globals_1.window === null || globals_1.window === void 0 ? void 0 : globals_1.window.screen) {
151
- if (globals_1.window.screen.height) {
152
- props.$screen_height = globals_1.window.screen.height;
153
- }
154
- if (globals_1.window.screen.width) {
155
- props.$screen_width = globals_1.window.screen.width;
156
- }
157
- }
158
- if (globals_1.window) {
159
- if (globals_1.window.innerHeight) {
160
- props.$viewport_height = globals_1.window.innerHeight;
161
- }
162
- if (globals_1.window.innerWidth) {
163
- props.$viewport_width = globals_1.window.innerWidth;
164
- }
165
- }
166
- // Library info
167
- props.$lib = "web";
168
- props.$lib_version = LIB_VERSION;
169
- // Insert ID for deduplication
170
- props.$insert_id = generateInsertId();
171
- // Timestamp (epoch time in seconds)
172
- props.$time = Date.now() / 1000;
173
- // Referrer properties (added to all events)
174
- props.$referrer = getReferrer();
175
- props.$referring_domain = getReferringDomain();
176
- return props;
275
+ return (0, index_2.extend)((0, index_2.stripEmptyProperties)({
276
+ $os: os_name,
277
+ $os_version: os_version,
278
+ $browser: (0, user_agent_utils_1.detectBrowser)(globals_1.userAgent, navigator.vendor),
279
+ $device: (0, user_agent_utils_1.detectDevice)(globals_1.userAgent),
280
+ $device_type: (0, user_agent_utils_1.detectDeviceType)(globals_1.userAgent),
281
+ $timezone: getTimezone(),
282
+ $timezone_offset: getTimezoneOffset(),
283
+ }), {
284
+ $current_url: (0, request_utils_1.maskQueryParams)(globals_1.location === null || globals_1.location === void 0 ? void 0 : globals_1.location.href, paramsToMask, exports.MASKED),
285
+ $host: globals_1.location === null || globals_1.location === void 0 ? void 0 : globals_1.location.host,
286
+ $pathname: globals_1.location === null || globals_1.location === void 0 ? void 0 : globals_1.location.pathname,
287
+ $raw_user_agent: globals_1.userAgent.length > 1000 ? globals_1.userAgent.substring(0, 997) + '...' : globals_1.userAgent,
288
+ $browser_version: (0, user_agent_utils_1.detectBrowserVersion)(globals_1.userAgent, navigator.vendor),
289
+ $browser_language: getBrowserLanguage(),
290
+ $browser_language_prefix: getBrowserLanguagePrefix(),
291
+ $screen_height: globals_1.window === null || globals_1.window === void 0 ? void 0 : globals_1.window.screen.height,
292
+ $screen_width: globals_1.window === null || globals_1.window === void 0 ? void 0 : globals_1.window.screen.width,
293
+ $viewport_height: globals_1.window === null || globals_1.window === void 0 ? void 0 : globals_1.window.innerHeight,
294
+ $viewport_width: globals_1.window === null || globals_1.window === void 0 ? void 0 : globals_1.window.innerWidth,
295
+ $lib: 'web',
296
+ $lib_version: LIB_VERSION,
297
+ $insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),
298
+ $time: Date.now() / 1000, // epoch time in seconds
299
+ });
177
300
  }