saasco-sdk 0.1.26 → 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 +87 -13
- package/index.esm.js +87 -13
- package/package.json +3 -2
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.
|
|
10
|
+
var version = "0.1.27";
|
|
10
11
|
|
|
11
12
|
const timezones = {
|
|
12
13
|
'Asia/Barnaul': 'RU',
|
|
@@ -496,12 +497,80 @@ const PREF = 'saasco-sdk';
|
|
|
496
497
|
const SESSION_DURATION = 1000 * 60 * 30;
|
|
497
498
|
const USER_DURATION = 1000 * 60 * 60 * 24 * 365;
|
|
498
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
|
+
}
|
|
499
568
|
function storeData(key, value, ttl) {
|
|
500
|
-
const item = {
|
|
501
|
-
value,
|
|
502
|
-
expiry: new Date().getTime() + ttl
|
|
503
|
-
};
|
|
504
569
|
if (isServer) {
|
|
570
|
+
const item = {
|
|
571
|
+
value,
|
|
572
|
+
expiry: new Date().getTime() + ttl
|
|
573
|
+
};
|
|
505
574
|
if (value === undefined) {
|
|
506
575
|
delete data[key];
|
|
507
576
|
return;
|
|
@@ -510,8 +579,11 @@ function storeData(key, value, ttl) {
|
|
|
510
579
|
return;
|
|
511
580
|
}
|
|
512
581
|
const fullKey = `${PREF}-${key}`;
|
|
513
|
-
if (value === undefined)
|
|
514
|
-
|
|
582
|
+
if (value === undefined) {
|
|
583
|
+
deleteCookie(fullKey);
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
setCookie(fullKey, JSON.stringify(value), ttl);
|
|
515
587
|
}
|
|
516
588
|
function retrieveData(key) {
|
|
517
589
|
if (isServer) {
|
|
@@ -524,17 +596,17 @@ function retrieveData(key) {
|
|
|
524
596
|
return item.value;
|
|
525
597
|
}
|
|
526
598
|
const fullKey = `${PREF}-${key}`;
|
|
527
|
-
const itemStr =
|
|
599
|
+
const itemStr = getCookie(fullKey);
|
|
528
600
|
if (!itemStr) {
|
|
529
601
|
return null;
|
|
530
602
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
603
|
+
try {
|
|
604
|
+
return JSON.parse(itemStr);
|
|
605
|
+
} catch (error) {
|
|
606
|
+
// If JSON parsing fails, remove the corrupted cookie
|
|
607
|
+
deleteCookie(fullKey);
|
|
535
608
|
return null;
|
|
536
609
|
}
|
|
537
|
-
return item.value;
|
|
538
610
|
}
|
|
539
611
|
function getSessionId() {
|
|
540
612
|
return retrieveData(`session-id`);
|
|
@@ -620,6 +692,8 @@ class Saasco {
|
|
|
620
692
|
if (isBrowser) {
|
|
621
693
|
window.saasco = this;
|
|
622
694
|
}
|
|
695
|
+
// Migrate existing localStorage data to cookies for cross-subdomain support
|
|
696
|
+
migrateFromLocalStorage();
|
|
623
697
|
this.log('Saasco initialized', this.config);
|
|
624
698
|
if (this.config.debug) this.log('Debug mode active. This will log all events to the console.');
|
|
625
699
|
if (!this.config.enabled) this.log('Analytics is disabled. No requests will be sent to the server.');
|
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.
|
|
6
|
+
var version = "0.1.27";
|
|
6
7
|
|
|
7
8
|
const timezones = {
|
|
8
9
|
'Asia/Barnaul': 'RU',
|
|
@@ -492,12 +493,80 @@ const PREF = 'saasco-sdk';
|
|
|
492
493
|
const SESSION_DURATION = 1000 * 60 * 30;
|
|
493
494
|
const USER_DURATION = 1000 * 60 * 60 * 24 * 365;
|
|
494
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
|
+
}
|
|
495
564
|
function storeData(key, value, ttl) {
|
|
496
|
-
const item = {
|
|
497
|
-
value,
|
|
498
|
-
expiry: new Date().getTime() + ttl
|
|
499
|
-
};
|
|
500
565
|
if (isServer) {
|
|
566
|
+
const item = {
|
|
567
|
+
value,
|
|
568
|
+
expiry: new Date().getTime() + ttl
|
|
569
|
+
};
|
|
501
570
|
if (value === undefined) {
|
|
502
571
|
delete data[key];
|
|
503
572
|
return;
|
|
@@ -506,8 +575,11 @@ function storeData(key, value, ttl) {
|
|
|
506
575
|
return;
|
|
507
576
|
}
|
|
508
577
|
const fullKey = `${PREF}-${key}`;
|
|
509
|
-
if (value === undefined)
|
|
510
|
-
|
|
578
|
+
if (value === undefined) {
|
|
579
|
+
deleteCookie(fullKey);
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
setCookie(fullKey, JSON.stringify(value), ttl);
|
|
511
583
|
}
|
|
512
584
|
function retrieveData(key) {
|
|
513
585
|
if (isServer) {
|
|
@@ -520,17 +592,17 @@ function retrieveData(key) {
|
|
|
520
592
|
return item.value;
|
|
521
593
|
}
|
|
522
594
|
const fullKey = `${PREF}-${key}`;
|
|
523
|
-
const itemStr =
|
|
595
|
+
const itemStr = getCookie(fullKey);
|
|
524
596
|
if (!itemStr) {
|
|
525
597
|
return null;
|
|
526
598
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
599
|
+
try {
|
|
600
|
+
return JSON.parse(itemStr);
|
|
601
|
+
} catch (error) {
|
|
602
|
+
// If JSON parsing fails, remove the corrupted cookie
|
|
603
|
+
deleteCookie(fullKey);
|
|
531
604
|
return null;
|
|
532
605
|
}
|
|
533
|
-
return item.value;
|
|
534
606
|
}
|
|
535
607
|
function getSessionId() {
|
|
536
608
|
return retrieveData(`session-id`);
|
|
@@ -616,6 +688,8 @@ class Saasco {
|
|
|
616
688
|
if (isBrowser) {
|
|
617
689
|
window.saasco = this;
|
|
618
690
|
}
|
|
691
|
+
// Migrate existing localStorage data to cookies for cross-subdomain support
|
|
692
|
+
migrateFromLocalStorage();
|
|
619
693
|
this.log('Saasco initialized', this.config);
|
|
620
694
|
if (this.config.debug) this.log('Debug mode active. This will log all events to the console.');
|
|
621
695
|
if (!this.config.enabled) this.log('Analytics is disabled. No requests will be sent to the server.');
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "saasco-sdk",
|
|
3
|
-
"version": "0.1.
|
|
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",
|