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 +67 -8
- package/index.esm.js +66 -9
- package/package.json +1 -1
- package/src/index.d.ts +1 -0
- package/src/lib/analytics.d.ts +7 -10
- package/src/lib/getBrowserContext.d.ts +1 -1
- package/src/lib/getUTMContext.d.ts +2 -0
- package/src/lib/tracking/types.d.ts +20 -0
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.
|
|
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)
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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.
|
|
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)
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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
package/src/index.d.ts
CHANGED
package/src/lib/analytics.d.ts
CHANGED
|
@@ -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?:
|
|
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
|
-
|
|
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
|
|
2
|
+
export declare function getBrowserContext(): BrowserContext;
|
|
@@ -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>;
|