saasco-sdk 0.1.24 → 0.1.26

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
@@ -6,7 +6,7 @@ var tslib = require('tslib');
6
6
  var uuid = require('@lukeed/uuid');
7
7
  var zod = require('zod');
8
8
 
9
- var version = "0.1.24";
9
+ var version = "0.1.26";
10
10
 
11
11
  const timezones = {
12
12
  'Asia/Barnaul': 'RU',
@@ -439,7 +439,7 @@ const timezones = {
439
439
  function getBrowserContext() {
440
440
  var _a;
441
441
  const isBrowser = typeof window !== 'undefined';
442
- if (!isBrowser) return;
442
+ if (!isBrowser) throw new Error('getBrowserContext can only be called in browser');
443
443
  const customNavigator = navigator;
444
444
  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
445
  // https://caniuse.com/?search=Intl.DateTimeFormat().resolvedOptions().timeZone
@@ -468,9 +468,33 @@ function getBrowserContext() {
468
468
  };
469
469
  }
470
470
 
471
+ function getUTMContext() {
472
+ const isBrowser = typeof window !== 'undefined';
473
+ if (!isBrowser) throw new Error('getUTMContext can only be called in browser');
474
+ const params = new URLSearchParams(window.location.search);
475
+ const $utmSource = params.get('utm_source');
476
+ const $utmMedium = params.get('utm_medium');
477
+ const $utmCampaign = params.get('utm_campaign');
478
+ const $utmTerm = params.get('utm_term');
479
+ const $utmContent = params.get('utm_content');
480
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, $utmSource ? {
481
+ $utmSource
482
+ } : {}), $utmMedium ? {
483
+ $utmMedium
484
+ } : {}), $utmCampaign ? {
485
+ $utmCampaign
486
+ } : {}), $utmTerm ? {
487
+ $utmTerm
488
+ } : {}), $utmContent ? {
489
+ $utmContent
490
+ } : {});
491
+ }
492
+
471
493
  const isBrowser = typeof window !== 'undefined';
472
494
  const isServer = !isBrowser;
473
495
  const PREF = 'saasco-sdk';
496
+ const SESSION_DURATION = 1000 * 60 * 30;
497
+ const USER_DURATION = 1000 * 60 * 60 * 24 * 365;
474
498
  const data = {};
475
499
  function storeData(key, value, ttl) {
476
500
  const item = {
@@ -521,7 +545,7 @@ function setSessionId({
521
545
  reset: false
522
546
  }) {
523
547
  const sessionId = reset ? uuid.v4() : getSessionId() || uuid.v4();
524
- storeData(`session-id`, sessionId, 1000 * 60 * 30);
548
+ storeData(`session-id`, sessionId, SESSION_DURATION);
525
549
  }
526
550
  function getAnonymousId() {
527
551
  return retrieveData(`anonymous-id`);
@@ -532,14 +556,31 @@ function setAnonymousId({
532
556
  reset: false
533
557
  }) {
534
558
  const anonymousId = reset ? uuid.v4() : getAnonymousId() || uuid.v4();
535
- storeData(`anonymous-id`, anonymousId, 1000 * 60 * 60 * 24 * 365);
559
+ storeData(`anonymous-id`, anonymousId, USER_DURATION);
536
560
  return anonymousId;
537
561
  }
538
562
  function getUserId() {
539
563
  return retrieveData(`user-id`);
540
564
  }
541
565
  function setUserId(userId) {
542
- storeData(`user-id`, userId, 1000 * 60 * 60 * 24 * 365);
566
+ storeData(`user-id`, userId, USER_DURATION);
567
+ }
568
+ function getSessionUTMContext() {
569
+ return retrieveData(`session-utm-context`);
570
+ }
571
+ function setSessionUTMContext(utmContext) {
572
+ storeData(`session-utm-context`, utmContext, SESSION_DURATION);
573
+ }
574
+ function handleSessionUTMContext() {
575
+ if (isServer) return null;
576
+ const utmContext = getUTMContext();
577
+ // If we have any utm data its current so we store it
578
+ const utmContextKeys = Object.keys(utmContext);
579
+ if (utmContextKeys.length > 0) {
580
+ setSessionUTMContext(utmContext);
581
+ }
582
+ // This will return the current data, or stored data if we have any
583
+ return utmContext || getSessionUTMContext() || null;
543
584
  }
544
585
  class Saasco {
545
586
  /**
@@ -618,8 +659,15 @@ class Saasco {
618
659
  const sessionId = (hasAction ? undefined : actionOrPayload.sessionId) || getSessionId();
619
660
  const anonymousId = (hasAction ? undefined : actionOrPayload.anonymousId) || getAnonymousId();
620
661
  const distinctId = (hasAction ? undefined : actionOrPayload.userId) || getUserId();
621
- // Only gets browser context if in the browser
622
- const browserContext = isBrowser ? getBrowserContext() || {} : {};
662
+ // Only gets browser and utm context if in the browser
663
+ let browserContext;
664
+ let utmContext;
665
+ if (isBrowser) {
666
+ browserContext = getBrowserContext();
667
+ // handle session utm context and set it if it exists
668
+ const sessionUTMContext = handleSessionUTMContext();
669
+ if (sessionUTMContext) utmContext = sessionUTMContext;
670
+ }
623
671
  const data = {
624
672
  id: uuid.v4(),
625
673
  timestamp: new Date().toISOString(),
@@ -629,7 +677,7 @@ class Saasco {
629
677
  anonymousId,
630
678
  distinctId,
631
679
  projectId: this.config.projectId,
632
- payload: JSON.stringify(Object.assign(Object.assign({}, browserContext), {
680
+ payload: JSON.stringify(Object.assign(Object.assign(Object.assign({}, browserContext), utmContext), {
633
681
  properties: properties || {}
634
682
  })),
635
683
  source: isBrowser ? 'client' : 'server',
@@ -712,6 +760,8 @@ class Saasco {
712
760
  *
713
761
  */
714
762
  logout() {
763
+ // Clear UTM data on logout
764
+ setSessionUTMContext(null);
715
765
  this.identify(null);
716
766
  }
717
767
  /**
@@ -837,8 +887,17 @@ const browserContextSchema = zod.z.object({
837
887
  $title: zod.z.string(),
838
888
  $userAgent: zod.z.string()
839
889
  });
890
+ const utmContextSchema = zod.z.object({
891
+ $utmSource: zod.z.string().optional(),
892
+ $utmMedium: zod.z.string().optional(),
893
+ $utmCampaign: zod.z.string().optional(),
894
+ $utmTerm: zod.z.string().optional(),
895
+ $utmContent: zod.z.string().optional()
896
+ });
840
897
 
841
898
  exports.Saasco = Saasco;
842
899
  exports.browserContextSchema = browserContextSchema;
843
900
  exports.getBrowserContext = getBrowserContext;
901
+ exports.getUTMContext = getUTMContext;
844
902
  exports.timezones = timezones;
903
+ exports.utmContextSchema = utmContextSchema;
package/index.esm.js CHANGED
@@ -2,7 +2,7 @@ import { __awaiter } from 'tslib';
2
2
  import { v4 } from '@lukeed/uuid';
3
3
  import { z } from 'zod';
4
4
 
5
- var version = "0.1.24";
5
+ var version = "0.1.26";
6
6
 
7
7
  const timezones = {
8
8
  'Asia/Barnaul': 'RU',
@@ -435,7 +435,7 @@ const timezones = {
435
435
  function getBrowserContext() {
436
436
  var _a;
437
437
  const isBrowser = typeof window !== 'undefined';
438
- if (!isBrowser) return;
438
+ if (!isBrowser) throw new Error('getBrowserContext can only be called in browser');
439
439
  const customNavigator = navigator;
440
440
  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
441
  // https://caniuse.com/?search=Intl.DateTimeFormat().resolvedOptions().timeZone
@@ -464,9 +464,33 @@ function getBrowserContext() {
464
464
  };
465
465
  }
466
466
 
467
+ function getUTMContext() {
468
+ const isBrowser = typeof window !== 'undefined';
469
+ if (!isBrowser) throw new Error('getUTMContext can only be called in browser');
470
+ const params = new URLSearchParams(window.location.search);
471
+ const $utmSource = params.get('utm_source');
472
+ const $utmMedium = params.get('utm_medium');
473
+ const $utmCampaign = params.get('utm_campaign');
474
+ const $utmTerm = params.get('utm_term');
475
+ const $utmContent = params.get('utm_content');
476
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, $utmSource ? {
477
+ $utmSource
478
+ } : {}), $utmMedium ? {
479
+ $utmMedium
480
+ } : {}), $utmCampaign ? {
481
+ $utmCampaign
482
+ } : {}), $utmTerm ? {
483
+ $utmTerm
484
+ } : {}), $utmContent ? {
485
+ $utmContent
486
+ } : {});
487
+ }
488
+
467
489
  const isBrowser = typeof window !== 'undefined';
468
490
  const isServer = !isBrowser;
469
491
  const PREF = 'saasco-sdk';
492
+ const SESSION_DURATION = 1000 * 60 * 30;
493
+ const USER_DURATION = 1000 * 60 * 60 * 24 * 365;
470
494
  const data = {};
471
495
  function storeData(key, value, ttl) {
472
496
  const item = {
@@ -517,7 +541,7 @@ function setSessionId({
517
541
  reset: false
518
542
  }) {
519
543
  const sessionId = reset ? v4() : getSessionId() || v4();
520
- storeData(`session-id`, sessionId, 1000 * 60 * 30);
544
+ storeData(`session-id`, sessionId, SESSION_DURATION);
521
545
  }
522
546
  function getAnonymousId() {
523
547
  return retrieveData(`anonymous-id`);
@@ -528,14 +552,31 @@ function setAnonymousId({
528
552
  reset: false
529
553
  }) {
530
554
  const anonymousId = reset ? v4() : getAnonymousId() || v4();
531
- storeData(`anonymous-id`, anonymousId, 1000 * 60 * 60 * 24 * 365);
555
+ storeData(`anonymous-id`, anonymousId, USER_DURATION);
532
556
  return anonymousId;
533
557
  }
534
558
  function getUserId() {
535
559
  return retrieveData(`user-id`);
536
560
  }
537
561
  function setUserId(userId) {
538
- storeData(`user-id`, userId, 1000 * 60 * 60 * 24 * 365);
562
+ storeData(`user-id`, userId, USER_DURATION);
563
+ }
564
+ function getSessionUTMContext() {
565
+ return retrieveData(`session-utm-context`);
566
+ }
567
+ function setSessionUTMContext(utmContext) {
568
+ storeData(`session-utm-context`, utmContext, SESSION_DURATION);
569
+ }
570
+ function handleSessionUTMContext() {
571
+ if (isServer) return null;
572
+ const utmContext = getUTMContext();
573
+ // If we have any utm data its current so we store it
574
+ const utmContextKeys = Object.keys(utmContext);
575
+ if (utmContextKeys.length > 0) {
576
+ setSessionUTMContext(utmContext);
577
+ }
578
+ // This will return the current data, or stored data if we have any
579
+ return utmContext || getSessionUTMContext() || null;
539
580
  }
540
581
  class Saasco {
541
582
  /**
@@ -614,8 +655,15 @@ class Saasco {
614
655
  const sessionId = (hasAction ? undefined : actionOrPayload.sessionId) || getSessionId();
615
656
  const anonymousId = (hasAction ? undefined : actionOrPayload.anonymousId) || getAnonymousId();
616
657
  const distinctId = (hasAction ? undefined : actionOrPayload.userId) || getUserId();
617
- // Only gets browser context if in the browser
618
- const browserContext = isBrowser ? getBrowserContext() || {} : {};
658
+ // Only gets browser and utm context if in the browser
659
+ let browserContext;
660
+ let utmContext;
661
+ if (isBrowser) {
662
+ browserContext = getBrowserContext();
663
+ // handle session utm context and set it if it exists
664
+ const sessionUTMContext = handleSessionUTMContext();
665
+ if (sessionUTMContext) utmContext = sessionUTMContext;
666
+ }
619
667
  const data = {
620
668
  id: v4(),
621
669
  timestamp: new Date().toISOString(),
@@ -625,7 +673,7 @@ class Saasco {
625
673
  anonymousId,
626
674
  distinctId,
627
675
  projectId: this.config.projectId,
628
- payload: JSON.stringify(Object.assign(Object.assign({}, browserContext), {
676
+ payload: JSON.stringify(Object.assign(Object.assign(Object.assign({}, browserContext), utmContext), {
629
677
  properties: properties || {}
630
678
  })),
631
679
  source: isBrowser ? 'client' : 'server',
@@ -708,6 +756,8 @@ class Saasco {
708
756
  *
709
757
  */
710
758
  logout() {
759
+ // Clear UTM data on logout
760
+ setSessionUTMContext(null);
711
761
  this.identify(null);
712
762
  }
713
763
  /**
@@ -833,5 +883,12 @@ const browserContextSchema = z.object({
833
883
  $title: z.string(),
834
884
  $userAgent: z.string()
835
885
  });
886
+ const utmContextSchema = z.object({
887
+ $utmSource: z.string().optional(),
888
+ $utmMedium: z.string().optional(),
889
+ $utmCampaign: z.string().optional(),
890
+ $utmTerm: z.string().optional(),
891
+ $utmContent: z.string().optional()
892
+ });
836
893
 
837
- export { Saasco, browserContextSchema, getBrowserContext, timezones };
894
+ export { Saasco, browserContextSchema, getBrowserContext, getUTMContext, timezones, utmContextSchema };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "saasco-sdk",
3
- "version": "0.1.24",
3
+ "version": "0.1.26",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.0",
6
6
  "@lukeed/uuid": "^2.0.1",
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';
@@ -11,11 +11,14 @@ type Identity = {
11
11
  anonymousId: string | number;
12
12
  userId?: string | number;
13
13
  };
14
+ type Context = {
15
+ active?: boolean;
16
+ };
14
17
  type TrackPayload = Identity & {
15
18
  event: string;
16
19
  sessionId?: string;
17
20
  properties?: Record<string, any>;
18
- context?: Record<string, any>;
21
+ context?: Context;
19
22
  };
20
23
  type DoRequestResponse = {
21
24
  success: boolean;
@@ -55,9 +58,7 @@ export declare class Saasco {
55
58
  * Client: track('User Signed Up', { plan: 'Pro' }, { source: 'client' })
56
59
  * Server: track({ event: 'User Signed Up', userId: 'user_123', properties: { plan: 'Pro' } })
57
60
  */
58
- track(action: string, properties?: Record<string, any>, context?: {
59
- active?: boolean;
60
- }): Promise<DoRequestResponse>;
61
+ track(action: string, properties?: Record<string, any>, context?: Context): Promise<DoRequestResponse>;
61
62
  track(payload: TrackPayload): Promise<DoRequestResponse>;
62
63
  /**
63
64
  * The page method lets you record page views on your website
@@ -75,12 +76,8 @@ export declare class Saasco {
75
76
  * @param properties A dictionary of traits you know about the user like their email, name, plan etc.
76
77
  * @param context Context for the identify call such as whether the user is active.
77
78
  */
78
- identify(properties: Record<string, any>, context?: {
79
- active?: boolean;
80
- }): Promise<DoRequestResponse>;
81
- identify(distinctId: string | number | null, properties?: Record<string, any>, context?: {
82
- active?: boolean;
83
- }): Promise<DoRequestResponse>;
79
+ identify(properties: Record<string, any>, context?: Context): Promise<DoRequestResponse>;
80
+ identify(distinctId: string | number | null, properties?: Record<string, any>, context?: Context): Promise<DoRequestResponse>;
84
81
  /**
85
82
  * This should only be called when the user logs out
86
83
  * It will reset the session, anonymous id, and user id
@@ -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>;