saasco-sdk 0.1.25 → 0.1.27

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/index.cjs.js CHANGED
@@ -4,9 +4,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var tslib = require('tslib');
6
6
  var uuid = require('@lukeed/uuid');
7
+ var psl = require('psl');
7
8
  var zod = require('zod');
8
9
 
9
- var version = "0.1.25";
10
+ var version = "0.1.27";
10
11
 
11
12
  const timezones = {
12
13
  'Asia/Barnaul': 'RU',
@@ -439,7 +440,7 @@ const timezones = {
439
440
  function getBrowserContext() {
440
441
  var _a;
441
442
  const isBrowser = typeof window !== 'undefined';
442
- if (!isBrowser) return;
443
+ if (!isBrowser) throw new Error('getBrowserContext can only be called in browser');
443
444
  const customNavigator = navigator;
444
445
  const $locale = (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.languages) && (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.languages.length) ? customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.languages[0] : (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.userLanguage) || (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.language) || (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.browserLanguage) || 'en';
445
446
  // https://caniuse.com/?search=Intl.DateTimeFormat().resolvedOptions().timeZone
@@ -468,16 +469,108 @@ function getBrowserContext() {
468
469
  };
469
470
  }
470
471
 
472
+ function getUTMContext() {
473
+ const isBrowser = typeof window !== 'undefined';
474
+ if (!isBrowser) throw new Error('getUTMContext can only be called in browser');
475
+ const params = new URLSearchParams(window.location.search);
476
+ const $utmSource = params.get('utm_source');
477
+ const $utmMedium = params.get('utm_medium');
478
+ const $utmCampaign = params.get('utm_campaign');
479
+ const $utmTerm = params.get('utm_term');
480
+ const $utmContent = params.get('utm_content');
481
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, $utmSource ? {
482
+ $utmSource
483
+ } : {}), $utmMedium ? {
484
+ $utmMedium
485
+ } : {}), $utmCampaign ? {
486
+ $utmCampaign
487
+ } : {}), $utmTerm ? {
488
+ $utmTerm
489
+ } : {}), $utmContent ? {
490
+ $utmContent
491
+ } : {});
492
+ }
493
+
471
494
  const isBrowser = typeof window !== 'undefined';
472
495
  const isServer = !isBrowser;
473
496
  const PREF = 'saasco-sdk';
497
+ const SESSION_DURATION = 1000 * 60 * 30;
498
+ const USER_DURATION = 1000 * 60 * 60 * 24 * 365;
474
499
  const data = {};
500
+ function getRootDomain() {
501
+ if (isServer) return;
502
+ const hostname = window.location.hostname;
503
+ if (!psl.isValid(hostname)) {
504
+ // If not a valid domain, don't set domain (for localhost, IP addresses, etc.)
505
+ return undefined;
506
+ }
507
+ const parsed = psl.parse(hostname);
508
+ if ('domain' in parsed && parsed.domain) {
509
+ return parsed.domain;
510
+ }
511
+ return undefined;
512
+ }
513
+ function setCookie(name, value, ttl) {
514
+ if (isServer) return;
515
+ const expires = new Date(Date.now() + ttl).toUTCString();
516
+ const domain = getRootDomain();
517
+ const cookieString = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/${domain ? `; domain=.${domain}` : ''}`;
518
+ document.cookie = cookieString;
519
+ }
520
+ function getCookie(name) {
521
+ if (isServer) return null;
522
+ const nameEQ = name + '=';
523
+ const ca = document.cookie.split(';');
524
+ for (let i = 0; i < ca.length; i++) {
525
+ let c = ca[i];
526
+ while (c.charAt(0) === ' ') c = c.substring(1, c.length);
527
+ if (c.indexOf(nameEQ) === 0) {
528
+ return decodeURIComponent(c.substring(nameEQ.length, c.length));
529
+ }
530
+ }
531
+ return null;
532
+ }
533
+ function deleteCookie(name) {
534
+ if (isServer) return;
535
+ const domain = getRootDomain();
536
+ const cookieString = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/${domain ? `; domain=.${domain}` : ''}`;
537
+ document.cookie = cookieString;
538
+ }
539
+ function migrateFromLocalStorage() {
540
+ if (isServer) return;
541
+ const keysToMigrate = [`${PREF}-session-id`, `${PREF}-anonymous-id`, `${PREF}-user-id`, `${PREF}-session-utm-context`];
542
+ keysToMigrate.forEach(key => {
543
+ try {
544
+ const value = localStorage.getItem(key);
545
+ if (value) {
546
+ // Parse the stored data to get the original TTL
547
+ const item = JSON.parse(value);
548
+ const now = new Date().getTime();
549
+ // Check if the data is still valid
550
+ if (item.expiry > now) {
551
+ // Calculate remaining TTL
552
+ const remainingTtl = item.expiry - now;
553
+ // Store in cookie with remaining TTL
554
+ setCookie(key, value, remainingTtl);
555
+ // Remove from localStorage after successful migration
556
+ localStorage.removeItem(key);
557
+ } else {
558
+ // Data has expired, just remove it
559
+ localStorage.removeItem(key);
560
+ }
561
+ }
562
+ } catch (error) {
563
+ // If there's an error parsing the data, remove the corrupted item
564
+ localStorage.removeItem(key);
565
+ }
566
+ });
567
+ }
475
568
  function storeData(key, value, ttl) {
476
- const item = {
477
- value,
478
- expiry: new Date().getTime() + ttl
479
- };
480
569
  if (isServer) {
570
+ const item = {
571
+ value,
572
+ expiry: new Date().getTime() + ttl
573
+ };
481
574
  if (value === undefined) {
482
575
  delete data[key];
483
576
  return;
@@ -486,8 +579,11 @@ function storeData(key, value, ttl) {
486
579
  return;
487
580
  }
488
581
  const fullKey = `${PREF}-${key}`;
489
- if (value === undefined) return window.localStorage.removeItem(fullKey);
490
- localStorage.setItem(fullKey, JSON.stringify(item));
582
+ if (value === undefined) {
583
+ deleteCookie(fullKey);
584
+ return;
585
+ }
586
+ setCookie(fullKey, JSON.stringify(value), ttl);
491
587
  }
492
588
  function retrieveData(key) {
493
589
  if (isServer) {
@@ -500,17 +596,17 @@ function retrieveData(key) {
500
596
  return item.value;
501
597
  }
502
598
  const fullKey = `${PREF}-${key}`;
503
- const itemStr = localStorage.getItem(fullKey);
599
+ const itemStr = getCookie(fullKey);
504
600
  if (!itemStr) {
505
601
  return null;
506
602
  }
507
- const item = JSON.parse(itemStr);
508
- const now = new Date();
509
- if (now.getTime() > item.expiry) {
510
- localStorage.removeItem(fullKey);
603
+ try {
604
+ return JSON.parse(itemStr);
605
+ } catch (error) {
606
+ // If JSON parsing fails, remove the corrupted cookie
607
+ deleteCookie(fullKey);
511
608
  return null;
512
609
  }
513
- return item.value;
514
610
  }
515
611
  function getSessionId() {
516
612
  return retrieveData(`session-id`);
@@ -521,7 +617,7 @@ function setSessionId({
521
617
  reset: false
522
618
  }) {
523
619
  const sessionId = reset ? uuid.v4() : getSessionId() || uuid.v4();
524
- storeData(`session-id`, sessionId, 1000 * 60 * 30);
620
+ storeData(`session-id`, sessionId, SESSION_DURATION);
525
621
  }
526
622
  function getAnonymousId() {
527
623
  return retrieveData(`anonymous-id`);
@@ -532,14 +628,31 @@ function setAnonymousId({
532
628
  reset: false
533
629
  }) {
534
630
  const anonymousId = reset ? uuid.v4() : getAnonymousId() || uuid.v4();
535
- storeData(`anonymous-id`, anonymousId, 1000 * 60 * 60 * 24 * 365);
631
+ storeData(`anonymous-id`, anonymousId, USER_DURATION);
536
632
  return anonymousId;
537
633
  }
538
634
  function getUserId() {
539
635
  return retrieveData(`user-id`);
540
636
  }
541
637
  function setUserId(userId) {
542
- storeData(`user-id`, userId, 1000 * 60 * 60 * 24 * 365);
638
+ storeData(`user-id`, userId, USER_DURATION);
639
+ }
640
+ function getSessionUTMContext() {
641
+ return retrieveData(`session-utm-context`);
642
+ }
643
+ function setSessionUTMContext(utmContext) {
644
+ storeData(`session-utm-context`, utmContext, SESSION_DURATION);
645
+ }
646
+ function handleSessionUTMContext() {
647
+ if (isServer) return null;
648
+ const utmContext = getUTMContext();
649
+ // If we have any utm data its current so we store it
650
+ const utmContextKeys = Object.keys(utmContext);
651
+ if (utmContextKeys.length > 0) {
652
+ setSessionUTMContext(utmContext);
653
+ }
654
+ // This will return the current data, or stored data if we have any
655
+ return utmContext || getSessionUTMContext() || null;
543
656
  }
544
657
  class Saasco {
545
658
  /**
@@ -579,6 +692,8 @@ class Saasco {
579
692
  if (isBrowser) {
580
693
  window.saasco = this;
581
694
  }
695
+ // Migrate existing localStorage data to cookies for cross-subdomain support
696
+ migrateFromLocalStorage();
582
697
  this.log('Saasco initialized', this.config);
583
698
  if (this.config.debug) this.log('Debug mode active. This will log all events to the console.');
584
699
  if (!this.config.enabled) this.log('Analytics is disabled. No requests will be sent to the server.');
@@ -618,8 +733,15 @@ class Saasco {
618
733
  const sessionId = (hasAction ? undefined : actionOrPayload.sessionId) || getSessionId();
619
734
  const anonymousId = (hasAction ? undefined : actionOrPayload.anonymousId) || getAnonymousId();
620
735
  const distinctId = (hasAction ? undefined : actionOrPayload.userId) || getUserId();
621
- // Only gets browser context if in the browser
622
- const browserContext = isBrowser ? getBrowserContext() || {} : {};
736
+ // Only gets browser and utm context if in the browser
737
+ let browserContext;
738
+ let utmContext;
739
+ if (isBrowser) {
740
+ browserContext = getBrowserContext();
741
+ // handle session utm context and set it if it exists
742
+ const sessionUTMContext = handleSessionUTMContext();
743
+ if (sessionUTMContext) utmContext = sessionUTMContext;
744
+ }
623
745
  const data = {
624
746
  id: uuid.v4(),
625
747
  timestamp: new Date().toISOString(),
@@ -629,7 +751,7 @@ class Saasco {
629
751
  anonymousId,
630
752
  distinctId,
631
753
  projectId: this.config.projectId,
632
- payload: JSON.stringify(Object.assign(Object.assign({}, browserContext), {
754
+ payload: JSON.stringify(Object.assign(Object.assign(Object.assign({}, browserContext), utmContext), {
633
755
  properties: properties || {}
634
756
  })),
635
757
  source: isBrowser ? 'client' : 'server',
@@ -712,6 +834,8 @@ class Saasco {
712
834
  *
713
835
  */
714
836
  logout() {
837
+ // Clear UTM data on logout
838
+ setSessionUTMContext(null);
715
839
  this.identify(null);
716
840
  }
717
841
  /**
@@ -837,8 +961,17 @@ const browserContextSchema = zod.z.object({
837
961
  $title: zod.z.string(),
838
962
  $userAgent: zod.z.string()
839
963
  });
964
+ const utmContextSchema = zod.z.object({
965
+ $utmSource: zod.z.string().optional(),
966
+ $utmMedium: zod.z.string().optional(),
967
+ $utmCampaign: zod.z.string().optional(),
968
+ $utmTerm: zod.z.string().optional(),
969
+ $utmContent: zod.z.string().optional()
970
+ });
840
971
 
841
972
  exports.Saasco = Saasco;
842
973
  exports.browserContextSchema = browserContextSchema;
843
974
  exports.getBrowserContext = getBrowserContext;
975
+ exports.getUTMContext = getUTMContext;
844
976
  exports.timezones = timezones;
977
+ exports.utmContextSchema = utmContextSchema;
package/index.esm.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { __awaiter } from 'tslib';
2
2
  import { v4 } from '@lukeed/uuid';
3
+ import { isValid, parse } from 'psl';
3
4
  import { z } from 'zod';
4
5
 
5
- var version = "0.1.25";
6
+ var version = "0.1.27";
6
7
 
7
8
  const timezones = {
8
9
  'Asia/Barnaul': 'RU',
@@ -435,7 +436,7 @@ const timezones = {
435
436
  function getBrowserContext() {
436
437
  var _a;
437
438
  const isBrowser = typeof window !== 'undefined';
438
- if (!isBrowser) return;
439
+ if (!isBrowser) throw new Error('getBrowserContext can only be called in browser');
439
440
  const customNavigator = navigator;
440
441
  const $locale = (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.languages) && (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.languages.length) ? customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.languages[0] : (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.userLanguage) || (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.language) || (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.browserLanguage) || 'en';
441
442
  // https://caniuse.com/?search=Intl.DateTimeFormat().resolvedOptions().timeZone
@@ -464,16 +465,108 @@ function getBrowserContext() {
464
465
  };
465
466
  }
466
467
 
468
+ function getUTMContext() {
469
+ const isBrowser = typeof window !== 'undefined';
470
+ if (!isBrowser) throw new Error('getUTMContext can only be called in browser');
471
+ const params = new URLSearchParams(window.location.search);
472
+ const $utmSource = params.get('utm_source');
473
+ const $utmMedium = params.get('utm_medium');
474
+ const $utmCampaign = params.get('utm_campaign');
475
+ const $utmTerm = params.get('utm_term');
476
+ const $utmContent = params.get('utm_content');
477
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, $utmSource ? {
478
+ $utmSource
479
+ } : {}), $utmMedium ? {
480
+ $utmMedium
481
+ } : {}), $utmCampaign ? {
482
+ $utmCampaign
483
+ } : {}), $utmTerm ? {
484
+ $utmTerm
485
+ } : {}), $utmContent ? {
486
+ $utmContent
487
+ } : {});
488
+ }
489
+
467
490
  const isBrowser = typeof window !== 'undefined';
468
491
  const isServer = !isBrowser;
469
492
  const PREF = 'saasco-sdk';
493
+ const SESSION_DURATION = 1000 * 60 * 30;
494
+ const USER_DURATION = 1000 * 60 * 60 * 24 * 365;
470
495
  const data = {};
496
+ function getRootDomain() {
497
+ if (isServer) return;
498
+ const hostname = window.location.hostname;
499
+ if (!isValid(hostname)) {
500
+ // If not a valid domain, don't set domain (for localhost, IP addresses, etc.)
501
+ return undefined;
502
+ }
503
+ const parsed = parse(hostname);
504
+ if ('domain' in parsed && parsed.domain) {
505
+ return parsed.domain;
506
+ }
507
+ return undefined;
508
+ }
509
+ function setCookie(name, value, ttl) {
510
+ if (isServer) return;
511
+ const expires = new Date(Date.now() + ttl).toUTCString();
512
+ const domain = getRootDomain();
513
+ const cookieString = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/${domain ? `; domain=.${domain}` : ''}`;
514
+ document.cookie = cookieString;
515
+ }
516
+ function getCookie(name) {
517
+ if (isServer) return null;
518
+ const nameEQ = name + '=';
519
+ const ca = document.cookie.split(';');
520
+ for (let i = 0; i < ca.length; i++) {
521
+ let c = ca[i];
522
+ while (c.charAt(0) === ' ') c = c.substring(1, c.length);
523
+ if (c.indexOf(nameEQ) === 0) {
524
+ return decodeURIComponent(c.substring(nameEQ.length, c.length));
525
+ }
526
+ }
527
+ return null;
528
+ }
529
+ function deleteCookie(name) {
530
+ if (isServer) return;
531
+ const domain = getRootDomain();
532
+ const cookieString = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/${domain ? `; domain=.${domain}` : ''}`;
533
+ document.cookie = cookieString;
534
+ }
535
+ function migrateFromLocalStorage() {
536
+ if (isServer) return;
537
+ const keysToMigrate = [`${PREF}-session-id`, `${PREF}-anonymous-id`, `${PREF}-user-id`, `${PREF}-session-utm-context`];
538
+ keysToMigrate.forEach(key => {
539
+ try {
540
+ const value = localStorage.getItem(key);
541
+ if (value) {
542
+ // Parse the stored data to get the original TTL
543
+ const item = JSON.parse(value);
544
+ const now = new Date().getTime();
545
+ // Check if the data is still valid
546
+ if (item.expiry > now) {
547
+ // Calculate remaining TTL
548
+ const remainingTtl = item.expiry - now;
549
+ // Store in cookie with remaining TTL
550
+ setCookie(key, value, remainingTtl);
551
+ // Remove from localStorage after successful migration
552
+ localStorage.removeItem(key);
553
+ } else {
554
+ // Data has expired, just remove it
555
+ localStorage.removeItem(key);
556
+ }
557
+ }
558
+ } catch (error) {
559
+ // If there's an error parsing the data, remove the corrupted item
560
+ localStorage.removeItem(key);
561
+ }
562
+ });
563
+ }
471
564
  function storeData(key, value, ttl) {
472
- const item = {
473
- value,
474
- expiry: new Date().getTime() + ttl
475
- };
476
565
  if (isServer) {
566
+ const item = {
567
+ value,
568
+ expiry: new Date().getTime() + ttl
569
+ };
477
570
  if (value === undefined) {
478
571
  delete data[key];
479
572
  return;
@@ -482,8 +575,11 @@ function storeData(key, value, ttl) {
482
575
  return;
483
576
  }
484
577
  const fullKey = `${PREF}-${key}`;
485
- if (value === undefined) return window.localStorage.removeItem(fullKey);
486
- localStorage.setItem(fullKey, JSON.stringify(item));
578
+ if (value === undefined) {
579
+ deleteCookie(fullKey);
580
+ return;
581
+ }
582
+ setCookie(fullKey, JSON.stringify(value), ttl);
487
583
  }
488
584
  function retrieveData(key) {
489
585
  if (isServer) {
@@ -496,17 +592,17 @@ function retrieveData(key) {
496
592
  return item.value;
497
593
  }
498
594
  const fullKey = `${PREF}-${key}`;
499
- const itemStr = localStorage.getItem(fullKey);
595
+ const itemStr = getCookie(fullKey);
500
596
  if (!itemStr) {
501
597
  return null;
502
598
  }
503
- const item = JSON.parse(itemStr);
504
- const now = new Date();
505
- if (now.getTime() > item.expiry) {
506
- localStorage.removeItem(fullKey);
599
+ try {
600
+ return JSON.parse(itemStr);
601
+ } catch (error) {
602
+ // If JSON parsing fails, remove the corrupted cookie
603
+ deleteCookie(fullKey);
507
604
  return null;
508
605
  }
509
- return item.value;
510
606
  }
511
607
  function getSessionId() {
512
608
  return retrieveData(`session-id`);
@@ -517,7 +613,7 @@ function setSessionId({
517
613
  reset: false
518
614
  }) {
519
615
  const sessionId = reset ? v4() : getSessionId() || v4();
520
- storeData(`session-id`, sessionId, 1000 * 60 * 30);
616
+ storeData(`session-id`, sessionId, SESSION_DURATION);
521
617
  }
522
618
  function getAnonymousId() {
523
619
  return retrieveData(`anonymous-id`);
@@ -528,14 +624,31 @@ function setAnonymousId({
528
624
  reset: false
529
625
  }) {
530
626
  const anonymousId = reset ? v4() : getAnonymousId() || v4();
531
- storeData(`anonymous-id`, anonymousId, 1000 * 60 * 60 * 24 * 365);
627
+ storeData(`anonymous-id`, anonymousId, USER_DURATION);
532
628
  return anonymousId;
533
629
  }
534
630
  function getUserId() {
535
631
  return retrieveData(`user-id`);
536
632
  }
537
633
  function setUserId(userId) {
538
- storeData(`user-id`, userId, 1000 * 60 * 60 * 24 * 365);
634
+ storeData(`user-id`, userId, USER_DURATION);
635
+ }
636
+ function getSessionUTMContext() {
637
+ return retrieveData(`session-utm-context`);
638
+ }
639
+ function setSessionUTMContext(utmContext) {
640
+ storeData(`session-utm-context`, utmContext, SESSION_DURATION);
641
+ }
642
+ function handleSessionUTMContext() {
643
+ if (isServer) return null;
644
+ const utmContext = getUTMContext();
645
+ // If we have any utm data its current so we store it
646
+ const utmContextKeys = Object.keys(utmContext);
647
+ if (utmContextKeys.length > 0) {
648
+ setSessionUTMContext(utmContext);
649
+ }
650
+ // This will return the current data, or stored data if we have any
651
+ return utmContext || getSessionUTMContext() || null;
539
652
  }
540
653
  class Saasco {
541
654
  /**
@@ -575,6 +688,8 @@ class Saasco {
575
688
  if (isBrowser) {
576
689
  window.saasco = this;
577
690
  }
691
+ // Migrate existing localStorage data to cookies for cross-subdomain support
692
+ migrateFromLocalStorage();
578
693
  this.log('Saasco initialized', this.config);
579
694
  if (this.config.debug) this.log('Debug mode active. This will log all events to the console.');
580
695
  if (!this.config.enabled) this.log('Analytics is disabled. No requests will be sent to the server.');
@@ -614,8 +729,15 @@ class Saasco {
614
729
  const sessionId = (hasAction ? undefined : actionOrPayload.sessionId) || getSessionId();
615
730
  const anonymousId = (hasAction ? undefined : actionOrPayload.anonymousId) || getAnonymousId();
616
731
  const distinctId = (hasAction ? undefined : actionOrPayload.userId) || getUserId();
617
- // Only gets browser context if in the browser
618
- const browserContext = isBrowser ? getBrowserContext() || {} : {};
732
+ // Only gets browser and utm context if in the browser
733
+ let browserContext;
734
+ let utmContext;
735
+ if (isBrowser) {
736
+ browserContext = getBrowserContext();
737
+ // handle session utm context and set it if it exists
738
+ const sessionUTMContext = handleSessionUTMContext();
739
+ if (sessionUTMContext) utmContext = sessionUTMContext;
740
+ }
619
741
  const data = {
620
742
  id: v4(),
621
743
  timestamp: new Date().toISOString(),
@@ -625,7 +747,7 @@ class Saasco {
625
747
  anonymousId,
626
748
  distinctId,
627
749
  projectId: this.config.projectId,
628
- payload: JSON.stringify(Object.assign(Object.assign({}, browserContext), {
750
+ payload: JSON.stringify(Object.assign(Object.assign(Object.assign({}, browserContext), utmContext), {
629
751
  properties: properties || {}
630
752
  })),
631
753
  source: isBrowser ? 'client' : 'server',
@@ -708,6 +830,8 @@ class Saasco {
708
830
  *
709
831
  */
710
832
  logout() {
833
+ // Clear UTM data on logout
834
+ setSessionUTMContext(null);
711
835
  this.identify(null);
712
836
  }
713
837
  /**
@@ -833,5 +957,12 @@ const browserContextSchema = z.object({
833
957
  $title: z.string(),
834
958
  $userAgent: z.string()
835
959
  });
960
+ const utmContextSchema = z.object({
961
+ $utmSource: z.string().optional(),
962
+ $utmMedium: z.string().optional(),
963
+ $utmCampaign: z.string().optional(),
964
+ $utmTerm: z.string().optional(),
965
+ $utmContent: z.string().optional()
966
+ });
836
967
 
837
- export { Saasco, browserContextSchema, getBrowserContext, timezones };
968
+ export { Saasco, browserContextSchema, getBrowserContext, getUTMContext, timezones, utmContextSchema };
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "saasco-sdk",
3
- "version": "0.1.25",
3
+ "version": "0.1.27",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.0",
6
6
  "@lukeed/uuid": "^2.0.1",
7
- "zod": "^3.22.4"
7
+ "zod": "^3.22.4",
8
+ "psl": "^1.9.0"
8
9
  },
9
10
  "main": "./index.cjs.js",
10
11
  "typings": "./src/index.d.ts",
package/src/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './lib/analytics';
2
2
  export * from './lib/getBrowserContext';
3
+ export * from './lib/getUTMContext';
3
4
  export * from './lib/tracking';
4
5
  export * from './lib/timezones';
@@ -1,2 +1,2 @@
1
1
  import { BrowserContext } from './tracking';
2
- export declare function getBrowserContext(): BrowserContext | undefined;
2
+ export declare function getBrowserContext(): BrowserContext;
@@ -0,0 +1,2 @@
1
+ import { UTMContext } from './tracking';
2
+ export declare function getUTMContext(): UTMContext;
@@ -34,3 +34,23 @@ export declare const browserContextSchema: z.ZodObject<{
34
34
  $userAgent: string;
35
35
  }>;
36
36
  export type BrowserContext = z.infer<typeof browserContextSchema>;
37
+ export declare const utmContextSchema: z.ZodObject<{
38
+ $utmSource: z.ZodOptional<z.ZodString>;
39
+ $utmMedium: z.ZodOptional<z.ZodString>;
40
+ $utmCampaign: z.ZodOptional<z.ZodString>;
41
+ $utmTerm: z.ZodOptional<z.ZodString>;
42
+ $utmContent: z.ZodOptional<z.ZodString>;
43
+ }, "strip", z.ZodTypeAny, {
44
+ $utmSource?: string | undefined;
45
+ $utmMedium?: string | undefined;
46
+ $utmCampaign?: string | undefined;
47
+ $utmTerm?: string | undefined;
48
+ $utmContent?: string | undefined;
49
+ }, {
50
+ $utmSource?: string | undefined;
51
+ $utmMedium?: string | undefined;
52
+ $utmCampaign?: string | undefined;
53
+ $utmTerm?: string | undefined;
54
+ $utmContent?: string | undefined;
55
+ }>;
56
+ export type UTMContext = z.infer<typeof utmContextSchema>;