@jitsu/js 1.9.9 → 1.9.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.
- package/.turbo/turbo-build.log +67 -67
- package/.turbo/turbo-clean.log +5 -5
- package/.turbo/turbo-test.log +472 -431
- package/README.md +1 -1
- package/__tests__/playwright/cases/reset.html +1 -0
- package/__tests__/playwright/integration.test.ts +3 -0
- package/dist/jitsu.cjs.js +60 -12
- package/dist/jitsu.es.js +60 -12
- package/dist/web/p.js.txt +60 -12
- package/package.json +3 -3
- package/src/analytics-plugin.ts +60 -10
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
window.testOnload = async j => {
|
|
11
11
|
await j.setAnonymousId("john-doe-id-1");
|
|
12
12
|
await j.identify("john-nondoe", { email: "john@example.com" });
|
|
13
|
+
await j.identify("john-nondoe", { email: "john2@example.com", $doNotSend: true });
|
|
13
14
|
await j.track("pageLoaded", { trackParam: "trackValue" });
|
|
14
15
|
await j.reset();
|
|
15
16
|
await j.track("pageLoaded", { trackParam: "trackValue" });
|
|
@@ -273,6 +273,9 @@ test("reset", async ({ browser }) => {
|
|
|
273
273
|
const newAnonymousId = cookies[0].value;
|
|
274
274
|
console.log(`🍪Cookies`, cookies);
|
|
275
275
|
|
|
276
|
+
//second identify call should not reach the server, but it should change the traits
|
|
277
|
+
expect(firstTrack.body.context.traits?.email).toEqual("john2@example.com");
|
|
278
|
+
|
|
276
279
|
expect(secondTrack.body.anonymousId).not.toBeNull();
|
|
277
280
|
expect(secondTrack.body.anonymousId).toBeDefined();
|
|
278
281
|
expect(secondTrack.body.anonymousId).toEqual(newAnonymousId);
|
package/dist/jitsu.cjs.js
CHANGED
|
@@ -1065,6 +1065,7 @@ const defaultConfig = {
|
|
|
1065
1065
|
fetchTimeoutMs: undefined,
|
|
1066
1066
|
s2s: undefined,
|
|
1067
1067
|
idEndpoint: undefined,
|
|
1068
|
+
errorPolicy: "log",
|
|
1068
1069
|
privacy: {
|
|
1069
1070
|
dontSend: false,
|
|
1070
1071
|
disableUserIds: false,
|
|
@@ -1401,18 +1402,19 @@ function urlPath(url) {
|
|
|
1401
1402
|
return "/" + pathMatch;
|
|
1402
1403
|
}
|
|
1403
1404
|
function adjustPayload(payload, config, storage, s2s) {
|
|
1404
|
-
var _a, _b, _c, _d, _e;
|
|
1405
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1405
1406
|
const runtime = config.runtime || (isInBrowser() ? windowRuntime(config) : emptyRuntime(config));
|
|
1406
1407
|
const url = runtime.pageUrl();
|
|
1407
1408
|
const parsedUrl = safeCall(() => new URL(url), undefined);
|
|
1408
1409
|
const query = parsedUrl ? parseQuery(parsedUrl.search) : {};
|
|
1409
1410
|
const properties = payload.properties || {};
|
|
1410
|
-
if (payload.type === "page" && url) {
|
|
1411
|
-
properties.url
|
|
1412
|
-
properties.
|
|
1411
|
+
if (payload.type === "page" && (properties.url || url)) {
|
|
1412
|
+
const targetUrl = properties.url || url;
|
|
1413
|
+
properties.url = targetUrl.replace(hashRegex, "");
|
|
1414
|
+
properties.path = fixPath(urlPath(targetUrl));
|
|
1413
1415
|
}
|
|
1414
|
-
const customContext = ((_a = payload.properties) === null || _a === void 0 ? void 0 : _a.context) || {};
|
|
1415
|
-
(
|
|
1416
|
+
const customContext = ((_a = payload.properties) === null || _a === void 0 ? void 0 : _a.context) || ((_b = payload.options) === null || _b === void 0 ? void 0 : _b.context) || {};
|
|
1417
|
+
(_c = payload.properties) === null || _c === void 0 ? true : delete _c.context;
|
|
1416
1418
|
const referrer = runtime.referrer();
|
|
1417
1419
|
const context = {
|
|
1418
1420
|
library: {
|
|
@@ -1420,7 +1422,7 @@ function adjustPayload(payload, config, storage, s2s) {
|
|
|
1420
1422
|
version: jitsuVersion,
|
|
1421
1423
|
env: isInBrowser() ? "browser" : "node",
|
|
1422
1424
|
},
|
|
1423
|
-
consent: ((
|
|
1425
|
+
consent: ((_d = config.privacy) === null || _d === void 0 ? void 0 : _d.consentCategories)
|
|
1424
1426
|
? {
|
|
1425
1427
|
categoryPreferences: config.privacy.consentCategories,
|
|
1426
1428
|
}
|
|
@@ -1439,14 +1441,14 @@ function adjustPayload(payload, config, storage, s2s) {
|
|
|
1439
1441
|
url: properties.url || url,
|
|
1440
1442
|
encoding: properties.encoding || runtime.documentEncoding(),
|
|
1441
1443
|
},
|
|
1442
|
-
clientIds: !((
|
|
1444
|
+
clientIds: !((_e = config.privacy) === null || _e === void 0 ? void 0 : _e.disableUserIds)
|
|
1443
1445
|
? Object.assign({ fbc: runtime.getCookie("_fbc"), fbp: runtime.getCookie("_fbp") }, getGa4Ids(runtime)) : undefined,
|
|
1444
1446
|
campaign: parseUtms(query),
|
|
1445
1447
|
};
|
|
1446
1448
|
const withContext = Object.assign(Object.assign({}, payload), { timestamp: new Date().toISOString(), sentAt: new Date().toISOString(), messageId: randomId(properties.path || (parsedUrl && parsedUrl.pathname)), writeKey: maskWriteKey(config.writeKey), groupId: storage.getItem("__group_id"), context: deepMerge(context, customContext) });
|
|
1447
1449
|
delete withContext.meta;
|
|
1448
1450
|
delete withContext.options;
|
|
1449
|
-
if ((
|
|
1451
|
+
if ((_f = config.privacy) === null || _f === void 0 ? void 0 : _f.disableUserIds) {
|
|
1450
1452
|
delete withContext.userId;
|
|
1451
1453
|
delete withContext.anonymousId;
|
|
1452
1454
|
delete withContext.context.traits;
|
|
@@ -1555,6 +1557,23 @@ function maskWriteKey(writeKey) {
|
|
|
1555
1557
|
}
|
|
1556
1558
|
return writeKey;
|
|
1557
1559
|
}
|
|
1560
|
+
function getErrorHandler(opts) {
|
|
1561
|
+
const configuredHandler = opts.errorPolicy || "log";
|
|
1562
|
+
if (typeof configuredHandler === "function") {
|
|
1563
|
+
return configuredHandler;
|
|
1564
|
+
}
|
|
1565
|
+
else if (configuredHandler === "rethrow") {
|
|
1566
|
+
return (msg, ...args) => {
|
|
1567
|
+
//ignore args, not clear what to do with them
|
|
1568
|
+
throw new Error(msg);
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
else {
|
|
1572
|
+
return (msg, ...args) => {
|
|
1573
|
+
console.error(msg, ...args);
|
|
1574
|
+
};
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1558
1577
|
function send(method, payload, jitsuConfig, instance, store) {
|
|
1559
1578
|
return __awaiter$1(this, void 0, void 0, function* () {
|
|
1560
1579
|
var _a, _b;
|
|
@@ -1566,6 +1585,7 @@ function send(method, payload, jitsuConfig, instance, store) {
|
|
|
1566
1585
|
const url = s2s ? `${jitsuConfig.host}/api/s/s2s/${method}` : `${jitsuConfig.host}/api/s/${method}`;
|
|
1567
1586
|
const fetch = jitsuConfig.fetch || globalThis.fetch;
|
|
1568
1587
|
if (!fetch) {
|
|
1588
|
+
//don't run it through error handler since error is critical and should be addressed
|
|
1569
1589
|
throw new Error("Please specify fetch function in jitsu plugin initialization, fetch isn't available in global scope");
|
|
1570
1590
|
}
|
|
1571
1591
|
const debugHeader = jitsuConfig.debug ? { "X-Enable-Debug": "true" } : {};
|
|
@@ -1596,7 +1616,8 @@ function send(method, payload, jitsuConfig, instance, store) {
|
|
|
1596
1616
|
}
|
|
1597
1617
|
}
|
|
1598
1618
|
catch (e) {
|
|
1599
|
-
|
|
1619
|
+
getErrorHandler(jitsuConfig)(`Call to ${url} failed with error ${e.message}`);
|
|
1620
|
+
return Promise.resolve();
|
|
1600
1621
|
}
|
|
1601
1622
|
let responseText;
|
|
1602
1623
|
try {
|
|
@@ -1616,7 +1637,8 @@ function send(method, payload, jitsuConfig, instance, store) {
|
|
|
1616
1637
|
responseJson = JSON.parse(responseText);
|
|
1617
1638
|
}
|
|
1618
1639
|
catch (e) {
|
|
1619
|
-
|
|
1640
|
+
getErrorHandler(jitsuConfig)(`Can't parse JSON: ${responseText}: ${e === null || e === void 0 ? void 0 : e.message}`);
|
|
1641
|
+
return Promise.resolve();
|
|
1620
1642
|
}
|
|
1621
1643
|
if (responseJson.destinations && responseJson.destinations.length > 0) {
|
|
1622
1644
|
if (jitsuConfig.s2s) {
|
|
@@ -1635,6 +1657,22 @@ function send(method, payload, jitsuConfig, instance, store) {
|
|
|
1635
1657
|
return adjustedPayload;
|
|
1636
1658
|
});
|
|
1637
1659
|
}
|
|
1660
|
+
const controllingTraits = ["$doNotSend"];
|
|
1661
|
+
/**
|
|
1662
|
+
* Remove all members of traits that controls identify/group behavior (see analytics.d.ts), and should not be recorded. Returns
|
|
1663
|
+
* copy of the object with these members removed.
|
|
1664
|
+
*
|
|
1665
|
+
* Do not modify traits object, but creates one
|
|
1666
|
+
* @param traits
|
|
1667
|
+
*/
|
|
1668
|
+
function stripControllingTraits(traits) {
|
|
1669
|
+
const res = Object.assign({}, traits);
|
|
1670
|
+
// see Traits definition in analytics.d.ts. We cannot define const here, so here's a little code duplication
|
|
1671
|
+
for (const key of controllingTraits) {
|
|
1672
|
+
delete res[key];
|
|
1673
|
+
}
|
|
1674
|
+
return res;
|
|
1675
|
+
}
|
|
1638
1676
|
const jitsuAnalyticsPlugin = (jitsuOptions = {}, storage) => {
|
|
1639
1677
|
// just to make sure that all undefined values are replaced with defaultConfig values
|
|
1640
1678
|
mergeConfig(jitsuOptions, jitsuOptions);
|
|
@@ -1693,16 +1731,21 @@ const jitsuAnalyticsPlugin = (jitsuOptions = {}, storage) => {
|
|
|
1693
1731
|
return send("track", payload, config, instance, storage);
|
|
1694
1732
|
},
|
|
1695
1733
|
identify: args => {
|
|
1696
|
-
var _a, _b;
|
|
1734
|
+
var _a, _b, _c;
|
|
1697
1735
|
const { payload, config, instance } = args;
|
|
1698
1736
|
if (((_a = config.privacy) === null || _a === void 0 ? void 0 : _a.dontSend) || ((_b = config.privacy) === null || _b === void 0 ? void 0 : _b.disableUserIds)) {
|
|
1699
1737
|
return;
|
|
1700
1738
|
}
|
|
1701
1739
|
// Store traits in cache to be able to use them in page and track events that run asynchronously with current identify.
|
|
1702
1740
|
storage.setItem("__user_id", payload.userId);
|
|
1741
|
+
const doNotSend = (_c = payload.traits) === null || _c === void 0 ? void 0 : _c.$doNotSend;
|
|
1703
1742
|
if (payload.traits && typeof payload.traits === "object") {
|
|
1743
|
+
payload.traits = stripControllingTraits(payload.traits);
|
|
1704
1744
|
storage.setItem("__user_traits", payload.traits);
|
|
1705
1745
|
}
|
|
1746
|
+
if (doNotSend) {
|
|
1747
|
+
return Promise.resolve();
|
|
1748
|
+
}
|
|
1706
1749
|
return send("identify", payload, config, instance, storage);
|
|
1707
1750
|
},
|
|
1708
1751
|
reset: args => {
|
|
@@ -1747,9 +1790,14 @@ const jitsuAnalyticsPlugin = (jitsuOptions = {}, storage) => {
|
|
|
1747
1790
|
const userId = (options === null || options === void 0 ? void 0 : options.userId) || (user === null || user === void 0 ? void 0 : user.userId);
|
|
1748
1791
|
const anonymousId = (options === null || options === void 0 ? void 0 : options.anonymousId) || (user === null || user === void 0 ? void 0 : user.anonymousId) || storage.getItem("__anon_id");
|
|
1749
1792
|
storage.setItem("__group_id", groupId);
|
|
1793
|
+
const doNotSend = traits === null || traits === void 0 ? void 0 : traits.$doNotSend;
|
|
1750
1794
|
if (traits && typeof traits === "object") {
|
|
1795
|
+
traits = stripControllingTraits(traits);
|
|
1751
1796
|
storage.setItem("__group_traits", traits);
|
|
1752
1797
|
}
|
|
1798
|
+
if (doNotSend) {
|
|
1799
|
+
return Promise.resolve();
|
|
1800
|
+
}
|
|
1753
1801
|
return send("group", Object.assign(Object.assign({ type: "group", groupId, traits }, (anonymousId ? { anonymousId } : {})), (userId ? { userId } : {})), jitsuOptions, instance, storage);
|
|
1754
1802
|
},
|
|
1755
1803
|
},
|
package/dist/jitsu.es.js
CHANGED
|
@@ -1063,6 +1063,7 @@ const defaultConfig = {
|
|
|
1063
1063
|
fetchTimeoutMs: undefined,
|
|
1064
1064
|
s2s: undefined,
|
|
1065
1065
|
idEndpoint: undefined,
|
|
1066
|
+
errorPolicy: "log",
|
|
1066
1067
|
privacy: {
|
|
1067
1068
|
dontSend: false,
|
|
1068
1069
|
disableUserIds: false,
|
|
@@ -1399,18 +1400,19 @@ function urlPath(url) {
|
|
|
1399
1400
|
return "/" + pathMatch;
|
|
1400
1401
|
}
|
|
1401
1402
|
function adjustPayload(payload, config, storage, s2s) {
|
|
1402
|
-
var _a, _b, _c, _d, _e;
|
|
1403
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1403
1404
|
const runtime = config.runtime || (isInBrowser() ? windowRuntime(config) : emptyRuntime(config));
|
|
1404
1405
|
const url = runtime.pageUrl();
|
|
1405
1406
|
const parsedUrl = safeCall(() => new URL(url), undefined);
|
|
1406
1407
|
const query = parsedUrl ? parseQuery(parsedUrl.search) : {};
|
|
1407
1408
|
const properties = payload.properties || {};
|
|
1408
|
-
if (payload.type === "page" && url) {
|
|
1409
|
-
properties.url
|
|
1410
|
-
properties.
|
|
1409
|
+
if (payload.type === "page" && (properties.url || url)) {
|
|
1410
|
+
const targetUrl = properties.url || url;
|
|
1411
|
+
properties.url = targetUrl.replace(hashRegex, "");
|
|
1412
|
+
properties.path = fixPath(urlPath(targetUrl));
|
|
1411
1413
|
}
|
|
1412
|
-
const customContext = ((_a = payload.properties) === null || _a === void 0 ? void 0 : _a.context) || {};
|
|
1413
|
-
(
|
|
1414
|
+
const customContext = ((_a = payload.properties) === null || _a === void 0 ? void 0 : _a.context) || ((_b = payload.options) === null || _b === void 0 ? void 0 : _b.context) || {};
|
|
1415
|
+
(_c = payload.properties) === null || _c === void 0 ? true : delete _c.context;
|
|
1414
1416
|
const referrer = runtime.referrer();
|
|
1415
1417
|
const context = {
|
|
1416
1418
|
library: {
|
|
@@ -1418,7 +1420,7 @@ function adjustPayload(payload, config, storage, s2s) {
|
|
|
1418
1420
|
version: jitsuVersion,
|
|
1419
1421
|
env: isInBrowser() ? "browser" : "node",
|
|
1420
1422
|
},
|
|
1421
|
-
consent: ((
|
|
1423
|
+
consent: ((_d = config.privacy) === null || _d === void 0 ? void 0 : _d.consentCategories)
|
|
1422
1424
|
? {
|
|
1423
1425
|
categoryPreferences: config.privacy.consentCategories,
|
|
1424
1426
|
}
|
|
@@ -1437,14 +1439,14 @@ function adjustPayload(payload, config, storage, s2s) {
|
|
|
1437
1439
|
url: properties.url || url,
|
|
1438
1440
|
encoding: properties.encoding || runtime.documentEncoding(),
|
|
1439
1441
|
},
|
|
1440
|
-
clientIds: !((
|
|
1442
|
+
clientIds: !((_e = config.privacy) === null || _e === void 0 ? void 0 : _e.disableUserIds)
|
|
1441
1443
|
? Object.assign({ fbc: runtime.getCookie("_fbc"), fbp: runtime.getCookie("_fbp") }, getGa4Ids(runtime)) : undefined,
|
|
1442
1444
|
campaign: parseUtms(query),
|
|
1443
1445
|
};
|
|
1444
1446
|
const withContext = Object.assign(Object.assign({}, payload), { timestamp: new Date().toISOString(), sentAt: new Date().toISOString(), messageId: randomId(properties.path || (parsedUrl && parsedUrl.pathname)), writeKey: maskWriteKey(config.writeKey), groupId: storage.getItem("__group_id"), context: deepMerge(context, customContext) });
|
|
1445
1447
|
delete withContext.meta;
|
|
1446
1448
|
delete withContext.options;
|
|
1447
|
-
if ((
|
|
1449
|
+
if ((_f = config.privacy) === null || _f === void 0 ? void 0 : _f.disableUserIds) {
|
|
1448
1450
|
delete withContext.userId;
|
|
1449
1451
|
delete withContext.anonymousId;
|
|
1450
1452
|
delete withContext.context.traits;
|
|
@@ -1553,6 +1555,23 @@ function maskWriteKey(writeKey) {
|
|
|
1553
1555
|
}
|
|
1554
1556
|
return writeKey;
|
|
1555
1557
|
}
|
|
1558
|
+
function getErrorHandler(opts) {
|
|
1559
|
+
const configuredHandler = opts.errorPolicy || "log";
|
|
1560
|
+
if (typeof configuredHandler === "function") {
|
|
1561
|
+
return configuredHandler;
|
|
1562
|
+
}
|
|
1563
|
+
else if (configuredHandler === "rethrow") {
|
|
1564
|
+
return (msg, ...args) => {
|
|
1565
|
+
//ignore args, not clear what to do with them
|
|
1566
|
+
throw new Error(msg);
|
|
1567
|
+
};
|
|
1568
|
+
}
|
|
1569
|
+
else {
|
|
1570
|
+
return (msg, ...args) => {
|
|
1571
|
+
console.error(msg, ...args);
|
|
1572
|
+
};
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1556
1575
|
function send(method, payload, jitsuConfig, instance, store) {
|
|
1557
1576
|
return __awaiter$1(this, void 0, void 0, function* () {
|
|
1558
1577
|
var _a, _b;
|
|
@@ -1564,6 +1583,7 @@ function send(method, payload, jitsuConfig, instance, store) {
|
|
|
1564
1583
|
const url = s2s ? `${jitsuConfig.host}/api/s/s2s/${method}` : `${jitsuConfig.host}/api/s/${method}`;
|
|
1565
1584
|
const fetch = jitsuConfig.fetch || globalThis.fetch;
|
|
1566
1585
|
if (!fetch) {
|
|
1586
|
+
//don't run it through error handler since error is critical and should be addressed
|
|
1567
1587
|
throw new Error("Please specify fetch function in jitsu plugin initialization, fetch isn't available in global scope");
|
|
1568
1588
|
}
|
|
1569
1589
|
const debugHeader = jitsuConfig.debug ? { "X-Enable-Debug": "true" } : {};
|
|
@@ -1594,7 +1614,8 @@ function send(method, payload, jitsuConfig, instance, store) {
|
|
|
1594
1614
|
}
|
|
1595
1615
|
}
|
|
1596
1616
|
catch (e) {
|
|
1597
|
-
|
|
1617
|
+
getErrorHandler(jitsuConfig)(`Call to ${url} failed with error ${e.message}`);
|
|
1618
|
+
return Promise.resolve();
|
|
1598
1619
|
}
|
|
1599
1620
|
let responseText;
|
|
1600
1621
|
try {
|
|
@@ -1614,7 +1635,8 @@ function send(method, payload, jitsuConfig, instance, store) {
|
|
|
1614
1635
|
responseJson = JSON.parse(responseText);
|
|
1615
1636
|
}
|
|
1616
1637
|
catch (e) {
|
|
1617
|
-
|
|
1638
|
+
getErrorHandler(jitsuConfig)(`Can't parse JSON: ${responseText}: ${e === null || e === void 0 ? void 0 : e.message}`);
|
|
1639
|
+
return Promise.resolve();
|
|
1618
1640
|
}
|
|
1619
1641
|
if (responseJson.destinations && responseJson.destinations.length > 0) {
|
|
1620
1642
|
if (jitsuConfig.s2s) {
|
|
@@ -1633,6 +1655,22 @@ function send(method, payload, jitsuConfig, instance, store) {
|
|
|
1633
1655
|
return adjustedPayload;
|
|
1634
1656
|
});
|
|
1635
1657
|
}
|
|
1658
|
+
const controllingTraits = ["$doNotSend"];
|
|
1659
|
+
/**
|
|
1660
|
+
* Remove all members of traits that controls identify/group behavior (see analytics.d.ts), and should not be recorded. Returns
|
|
1661
|
+
* copy of the object with these members removed.
|
|
1662
|
+
*
|
|
1663
|
+
* Do not modify traits object, but creates one
|
|
1664
|
+
* @param traits
|
|
1665
|
+
*/
|
|
1666
|
+
function stripControllingTraits(traits) {
|
|
1667
|
+
const res = Object.assign({}, traits);
|
|
1668
|
+
// see Traits definition in analytics.d.ts. We cannot define const here, so here's a little code duplication
|
|
1669
|
+
for (const key of controllingTraits) {
|
|
1670
|
+
delete res[key];
|
|
1671
|
+
}
|
|
1672
|
+
return res;
|
|
1673
|
+
}
|
|
1636
1674
|
const jitsuAnalyticsPlugin = (jitsuOptions = {}, storage) => {
|
|
1637
1675
|
// just to make sure that all undefined values are replaced with defaultConfig values
|
|
1638
1676
|
mergeConfig(jitsuOptions, jitsuOptions);
|
|
@@ -1691,16 +1729,21 @@ const jitsuAnalyticsPlugin = (jitsuOptions = {}, storage) => {
|
|
|
1691
1729
|
return send("track", payload, config, instance, storage);
|
|
1692
1730
|
},
|
|
1693
1731
|
identify: args => {
|
|
1694
|
-
var _a, _b;
|
|
1732
|
+
var _a, _b, _c;
|
|
1695
1733
|
const { payload, config, instance } = args;
|
|
1696
1734
|
if (((_a = config.privacy) === null || _a === void 0 ? void 0 : _a.dontSend) || ((_b = config.privacy) === null || _b === void 0 ? void 0 : _b.disableUserIds)) {
|
|
1697
1735
|
return;
|
|
1698
1736
|
}
|
|
1699
1737
|
// Store traits in cache to be able to use them in page and track events that run asynchronously with current identify.
|
|
1700
1738
|
storage.setItem("__user_id", payload.userId);
|
|
1739
|
+
const doNotSend = (_c = payload.traits) === null || _c === void 0 ? void 0 : _c.$doNotSend;
|
|
1701
1740
|
if (payload.traits && typeof payload.traits === "object") {
|
|
1741
|
+
payload.traits = stripControllingTraits(payload.traits);
|
|
1702
1742
|
storage.setItem("__user_traits", payload.traits);
|
|
1703
1743
|
}
|
|
1744
|
+
if (doNotSend) {
|
|
1745
|
+
return Promise.resolve();
|
|
1746
|
+
}
|
|
1704
1747
|
return send("identify", payload, config, instance, storage);
|
|
1705
1748
|
},
|
|
1706
1749
|
reset: args => {
|
|
@@ -1745,9 +1788,14 @@ const jitsuAnalyticsPlugin = (jitsuOptions = {}, storage) => {
|
|
|
1745
1788
|
const userId = (options === null || options === void 0 ? void 0 : options.userId) || (user === null || user === void 0 ? void 0 : user.userId);
|
|
1746
1789
|
const anonymousId = (options === null || options === void 0 ? void 0 : options.anonymousId) || (user === null || user === void 0 ? void 0 : user.anonymousId) || storage.getItem("__anon_id");
|
|
1747
1790
|
storage.setItem("__group_id", groupId);
|
|
1791
|
+
const doNotSend = traits === null || traits === void 0 ? void 0 : traits.$doNotSend;
|
|
1748
1792
|
if (traits && typeof traits === "object") {
|
|
1793
|
+
traits = stripControllingTraits(traits);
|
|
1749
1794
|
storage.setItem("__group_traits", traits);
|
|
1750
1795
|
}
|
|
1796
|
+
if (doNotSend) {
|
|
1797
|
+
return Promise.resolve();
|
|
1798
|
+
}
|
|
1751
1799
|
return send("group", Object.assign(Object.assign({ type: "group", groupId, traits }, (anonymousId ? { anonymousId } : {})), (userId ? { userId } : {})), jitsuOptions, instance, storage);
|
|
1752
1800
|
},
|
|
1753
1801
|
},
|
package/dist/web/p.js.txt
CHANGED
|
@@ -1066,6 +1066,7 @@
|
|
|
1066
1066
|
fetchTimeoutMs: undefined,
|
|
1067
1067
|
s2s: undefined,
|
|
1068
1068
|
idEndpoint: undefined,
|
|
1069
|
+
errorPolicy: "log",
|
|
1069
1070
|
privacy: {
|
|
1070
1071
|
dontSend: false,
|
|
1071
1072
|
disableUserIds: false,
|
|
@@ -1402,18 +1403,19 @@
|
|
|
1402
1403
|
return "/" + pathMatch;
|
|
1403
1404
|
}
|
|
1404
1405
|
function adjustPayload(payload, config, storage, s2s) {
|
|
1405
|
-
var _a, _b, _c, _d, _e;
|
|
1406
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1406
1407
|
const runtime = config.runtime || (isInBrowser() ? windowRuntime(config) : emptyRuntime(config));
|
|
1407
1408
|
const url = runtime.pageUrl();
|
|
1408
1409
|
const parsedUrl = safeCall(() => new URL(url), undefined);
|
|
1409
1410
|
const query = parsedUrl ? parseQuery(parsedUrl.search) : {};
|
|
1410
1411
|
const properties = payload.properties || {};
|
|
1411
|
-
if (payload.type === "page" && url) {
|
|
1412
|
-
properties.url
|
|
1413
|
-
properties.
|
|
1412
|
+
if (payload.type === "page" && (properties.url || url)) {
|
|
1413
|
+
const targetUrl = properties.url || url;
|
|
1414
|
+
properties.url = targetUrl.replace(hashRegex, "");
|
|
1415
|
+
properties.path = fixPath(urlPath(targetUrl));
|
|
1414
1416
|
}
|
|
1415
|
-
const customContext = ((_a = payload.properties) === null || _a === void 0 ? void 0 : _a.context) || {};
|
|
1416
|
-
(
|
|
1417
|
+
const customContext = ((_a = payload.properties) === null || _a === void 0 ? void 0 : _a.context) || ((_b = payload.options) === null || _b === void 0 ? void 0 : _b.context) || {};
|
|
1418
|
+
(_c = payload.properties) === null || _c === void 0 ? true : delete _c.context;
|
|
1417
1419
|
const referrer = runtime.referrer();
|
|
1418
1420
|
const context = {
|
|
1419
1421
|
library: {
|
|
@@ -1421,7 +1423,7 @@
|
|
|
1421
1423
|
version: jitsuVersion,
|
|
1422
1424
|
env: isInBrowser() ? "browser" : "node",
|
|
1423
1425
|
},
|
|
1424
|
-
consent: ((
|
|
1426
|
+
consent: ((_d = config.privacy) === null || _d === void 0 ? void 0 : _d.consentCategories)
|
|
1425
1427
|
? {
|
|
1426
1428
|
categoryPreferences: config.privacy.consentCategories,
|
|
1427
1429
|
}
|
|
@@ -1440,14 +1442,14 @@
|
|
|
1440
1442
|
url: properties.url || url,
|
|
1441
1443
|
encoding: properties.encoding || runtime.documentEncoding(),
|
|
1442
1444
|
},
|
|
1443
|
-
clientIds: !((
|
|
1445
|
+
clientIds: !((_e = config.privacy) === null || _e === void 0 ? void 0 : _e.disableUserIds)
|
|
1444
1446
|
? Object.assign({ fbc: runtime.getCookie("_fbc"), fbp: runtime.getCookie("_fbp") }, getGa4Ids(runtime)) : undefined,
|
|
1445
1447
|
campaign: parseUtms(query),
|
|
1446
1448
|
};
|
|
1447
1449
|
const withContext = Object.assign(Object.assign({}, payload), { timestamp: new Date().toISOString(), sentAt: new Date().toISOString(), messageId: randomId(properties.path || (parsedUrl && parsedUrl.pathname)), writeKey: maskWriteKey(config.writeKey), groupId: storage.getItem("__group_id"), context: deepMerge(context, customContext) });
|
|
1448
1450
|
delete withContext.meta;
|
|
1449
1451
|
delete withContext.options;
|
|
1450
|
-
if ((
|
|
1452
|
+
if ((_f = config.privacy) === null || _f === void 0 ? void 0 : _f.disableUserIds) {
|
|
1451
1453
|
delete withContext.userId;
|
|
1452
1454
|
delete withContext.anonymousId;
|
|
1453
1455
|
delete withContext.context.traits;
|
|
@@ -1556,6 +1558,23 @@
|
|
|
1556
1558
|
}
|
|
1557
1559
|
return writeKey;
|
|
1558
1560
|
}
|
|
1561
|
+
function getErrorHandler(opts) {
|
|
1562
|
+
const configuredHandler = opts.errorPolicy || "log";
|
|
1563
|
+
if (typeof configuredHandler === "function") {
|
|
1564
|
+
return configuredHandler;
|
|
1565
|
+
}
|
|
1566
|
+
else if (configuredHandler === "rethrow") {
|
|
1567
|
+
return (msg, ...args) => {
|
|
1568
|
+
//ignore args, not clear what to do with them
|
|
1569
|
+
throw new Error(msg);
|
|
1570
|
+
};
|
|
1571
|
+
}
|
|
1572
|
+
else {
|
|
1573
|
+
return (msg, ...args) => {
|
|
1574
|
+
console.error(msg, ...args);
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1559
1578
|
function send(method, payload, jitsuConfig, instance, store) {
|
|
1560
1579
|
return __awaiter$1(this, void 0, void 0, function* () {
|
|
1561
1580
|
var _a, _b;
|
|
@@ -1567,6 +1586,7 @@
|
|
|
1567
1586
|
const url = s2s ? `${jitsuConfig.host}/api/s/s2s/${method}` : `${jitsuConfig.host}/api/s/${method}`;
|
|
1568
1587
|
const fetch = jitsuConfig.fetch || globalThis.fetch;
|
|
1569
1588
|
if (!fetch) {
|
|
1589
|
+
//don't run it through error handler since error is critical and should be addressed
|
|
1570
1590
|
throw new Error("Please specify fetch function in jitsu plugin initialization, fetch isn't available in global scope");
|
|
1571
1591
|
}
|
|
1572
1592
|
const debugHeader = jitsuConfig.debug ? { "X-Enable-Debug": "true" } : {};
|
|
@@ -1597,7 +1617,8 @@
|
|
|
1597
1617
|
}
|
|
1598
1618
|
}
|
|
1599
1619
|
catch (e) {
|
|
1600
|
-
|
|
1620
|
+
getErrorHandler(jitsuConfig)(`Call to ${url} failed with error ${e.message}`);
|
|
1621
|
+
return Promise.resolve();
|
|
1601
1622
|
}
|
|
1602
1623
|
let responseText;
|
|
1603
1624
|
try {
|
|
@@ -1617,7 +1638,8 @@
|
|
|
1617
1638
|
responseJson = JSON.parse(responseText);
|
|
1618
1639
|
}
|
|
1619
1640
|
catch (e) {
|
|
1620
|
-
|
|
1641
|
+
getErrorHandler(jitsuConfig)(`Can't parse JSON: ${responseText}: ${e === null || e === void 0 ? void 0 : e.message}`);
|
|
1642
|
+
return Promise.resolve();
|
|
1621
1643
|
}
|
|
1622
1644
|
if (responseJson.destinations && responseJson.destinations.length > 0) {
|
|
1623
1645
|
if (jitsuConfig.s2s) {
|
|
@@ -1636,6 +1658,22 @@
|
|
|
1636
1658
|
return adjustedPayload;
|
|
1637
1659
|
});
|
|
1638
1660
|
}
|
|
1661
|
+
const controllingTraits = ["$doNotSend"];
|
|
1662
|
+
/**
|
|
1663
|
+
* Remove all members of traits that controls identify/group behavior (see analytics.d.ts), and should not be recorded. Returns
|
|
1664
|
+
* copy of the object with these members removed.
|
|
1665
|
+
*
|
|
1666
|
+
* Do not modify traits object, but creates one
|
|
1667
|
+
* @param traits
|
|
1668
|
+
*/
|
|
1669
|
+
function stripControllingTraits(traits) {
|
|
1670
|
+
const res = Object.assign({}, traits);
|
|
1671
|
+
// see Traits definition in analytics.d.ts. We cannot define const here, so here's a little code duplication
|
|
1672
|
+
for (const key of controllingTraits) {
|
|
1673
|
+
delete res[key];
|
|
1674
|
+
}
|
|
1675
|
+
return res;
|
|
1676
|
+
}
|
|
1639
1677
|
const jitsuAnalyticsPlugin = (jitsuOptions = {}, storage) => {
|
|
1640
1678
|
// just to make sure that all undefined values are replaced with defaultConfig values
|
|
1641
1679
|
mergeConfig(jitsuOptions, jitsuOptions);
|
|
@@ -1694,16 +1732,21 @@
|
|
|
1694
1732
|
return send("track", payload, config, instance, storage);
|
|
1695
1733
|
},
|
|
1696
1734
|
identify: args => {
|
|
1697
|
-
var _a, _b;
|
|
1735
|
+
var _a, _b, _c;
|
|
1698
1736
|
const { payload, config, instance } = args;
|
|
1699
1737
|
if (((_a = config.privacy) === null || _a === void 0 ? void 0 : _a.dontSend) || ((_b = config.privacy) === null || _b === void 0 ? void 0 : _b.disableUserIds)) {
|
|
1700
1738
|
return;
|
|
1701
1739
|
}
|
|
1702
1740
|
// Store traits in cache to be able to use them in page and track events that run asynchronously with current identify.
|
|
1703
1741
|
storage.setItem("__user_id", payload.userId);
|
|
1742
|
+
const doNotSend = (_c = payload.traits) === null || _c === void 0 ? void 0 : _c.$doNotSend;
|
|
1704
1743
|
if (payload.traits && typeof payload.traits === "object") {
|
|
1744
|
+
payload.traits = stripControllingTraits(payload.traits);
|
|
1705
1745
|
storage.setItem("__user_traits", payload.traits);
|
|
1706
1746
|
}
|
|
1747
|
+
if (doNotSend) {
|
|
1748
|
+
return Promise.resolve();
|
|
1749
|
+
}
|
|
1707
1750
|
return send("identify", payload, config, instance, storage);
|
|
1708
1751
|
},
|
|
1709
1752
|
reset: args => {
|
|
@@ -1748,9 +1791,14 @@
|
|
|
1748
1791
|
const userId = (options === null || options === void 0 ? void 0 : options.userId) || (user === null || user === void 0 ? void 0 : user.userId);
|
|
1749
1792
|
const anonymousId = (options === null || options === void 0 ? void 0 : options.anonymousId) || (user === null || user === void 0 ? void 0 : user.anonymousId) || storage.getItem("__anon_id");
|
|
1750
1793
|
storage.setItem("__group_id", groupId);
|
|
1794
|
+
const doNotSend = traits === null || traits === void 0 ? void 0 : traits.$doNotSend;
|
|
1751
1795
|
if (traits && typeof traits === "object") {
|
|
1796
|
+
traits = stripControllingTraits(traits);
|
|
1752
1797
|
storage.setItem("__group_traits", traits);
|
|
1753
1798
|
}
|
|
1799
|
+
if (doNotSend) {
|
|
1800
|
+
return Promise.resolve();
|
|
1801
|
+
}
|
|
1754
1802
|
return send("group", Object.assign(Object.assign({ type: "group", groupId, traits }, (anonymousId ? { anonymousId } : {})), (userId ? { userId } : {})), jitsuOptions, instance, storage);
|
|
1755
1803
|
},
|
|
1756
1804
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jitsu/js",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.11",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Jitsu Dev Team <dev@jitsu.com>",
|
|
6
6
|
"main": "dist/jitsu.cjs.js",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"rollup": "^3.29.5",
|
|
36
36
|
"ts-jest": "29.0.5",
|
|
37
37
|
"typescript": "^5.6.3",
|
|
38
|
-
"@jitsu/protocols": "1.9.
|
|
39
|
-
"jsondiffpatch": "1.9.
|
|
38
|
+
"@jitsu/protocols": "1.9.11",
|
|
39
|
+
"jsondiffpatch": "1.9.11"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"analytics": "0.8.9"
|