@jitsu/js 1.9.10 → 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/__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/src/analytics-plugin.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
/* global analytics */
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
DynamicJitsuOptions,
|
|
5
|
-
JitsuOptions,
|
|
6
|
-
PersistentStorage,
|
|
7
|
-
RuntimeFacade,
|
|
8
4
|
AnalyticsClientEvent,
|
|
9
5
|
Callback,
|
|
6
|
+
DynamicJitsuOptions,
|
|
7
|
+
ErrorHandler,
|
|
10
8
|
ID,
|
|
9
|
+
JitsuOptions,
|
|
11
10
|
JSONObject,
|
|
12
11
|
Options,
|
|
12
|
+
PersistentStorage,
|
|
13
|
+
RuntimeFacade,
|
|
14
|
+
Traits,
|
|
13
15
|
} from "@jitsu/protocols/analytics";
|
|
14
16
|
import parse from "./index";
|
|
15
17
|
|
|
@@ -35,6 +37,7 @@ const defaultConfig: Required<JitsuOptions> = {
|
|
|
35
37
|
fetchTimeoutMs: undefined,
|
|
36
38
|
s2s: undefined,
|
|
37
39
|
idEndpoint: undefined,
|
|
40
|
+
errorPolicy: "log",
|
|
38
41
|
privacy: {
|
|
39
42
|
dontSend: false,
|
|
40
43
|
disableUserIds: false,
|
|
@@ -415,12 +418,13 @@ function adjustPayload(
|
|
|
415
418
|
const query = parsedUrl ? parseQuery(parsedUrl.search) : {};
|
|
416
419
|
const properties = payload.properties || {};
|
|
417
420
|
|
|
418
|
-
if (payload.type === "page" && url) {
|
|
419
|
-
properties.url
|
|
420
|
-
properties.
|
|
421
|
+
if (payload.type === "page" && (properties.url || url)) {
|
|
422
|
+
const targetUrl = properties.url || url;
|
|
423
|
+
properties.url = targetUrl.replace(hashRegex, "");
|
|
424
|
+
properties.path = fixPath(urlPath(targetUrl));
|
|
421
425
|
}
|
|
422
426
|
|
|
423
|
-
const customContext = payload.properties?.context || {};
|
|
427
|
+
const customContext = payload.properties?.context || payload.options?.context || {};
|
|
424
428
|
delete payload.properties?.context;
|
|
425
429
|
const referrer = runtime.referrer();
|
|
426
430
|
const context: AnalyticsClientEvent["context"] = {
|
|
@@ -627,6 +631,22 @@ function maskWriteKey(writeKey?: string): string | undefined {
|
|
|
627
631
|
return writeKey;
|
|
628
632
|
}
|
|
629
633
|
|
|
634
|
+
function getErrorHandler(opts: JitsuOptions): ErrorHandler {
|
|
635
|
+
const configuredHandler = opts.errorPolicy || "log";
|
|
636
|
+
if (typeof configuredHandler === "function") {
|
|
637
|
+
return configuredHandler;
|
|
638
|
+
} else if (configuredHandler === "rethrow") {
|
|
639
|
+
return (msg, ...args) => {
|
|
640
|
+
//ignore args, not clear what to do with them
|
|
641
|
+
throw new Error(msg);
|
|
642
|
+
};
|
|
643
|
+
} else {
|
|
644
|
+
return (msg, ...args) => {
|
|
645
|
+
console.error(msg, ...args);
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
630
650
|
async function send(
|
|
631
651
|
method,
|
|
632
652
|
payload,
|
|
@@ -642,6 +662,7 @@ async function send(
|
|
|
642
662
|
const url = s2s ? `${jitsuConfig.host}/api/s/s2s/${method}` : `${jitsuConfig.host}/api/s/${method}`;
|
|
643
663
|
const fetch = jitsuConfig.fetch || globalThis.fetch;
|
|
644
664
|
if (!fetch) {
|
|
665
|
+
//don't run it through error handler since error is critical and should be addressed
|
|
645
666
|
throw new Error(
|
|
646
667
|
"Please specify fetch function in jitsu plugin initialization, fetch isn't available in global scope"
|
|
647
668
|
);
|
|
@@ -681,7 +702,8 @@ async function send(
|
|
|
681
702
|
clearTimeout(abortTimeout);
|
|
682
703
|
}
|
|
683
704
|
} catch (e: any) {
|
|
684
|
-
|
|
705
|
+
getErrorHandler(jitsuConfig)(`Call to ${url} failed with error ${e.message}`);
|
|
706
|
+
return Promise.resolve();
|
|
685
707
|
}
|
|
686
708
|
let responseText;
|
|
687
709
|
try {
|
|
@@ -708,7 +730,8 @@ async function send(
|
|
|
708
730
|
try {
|
|
709
731
|
responseJson = JSON.parse(responseText);
|
|
710
732
|
} catch (e) {
|
|
711
|
-
|
|
733
|
+
getErrorHandler(jitsuConfig)(`Can't parse JSON: ${responseText}: ${e?.message}`);
|
|
734
|
+
return Promise.resolve();
|
|
712
735
|
}
|
|
713
736
|
|
|
714
737
|
if (responseJson.destinations && responseJson.destinations.length > 0) {
|
|
@@ -730,6 +753,23 @@ async function send(
|
|
|
730
753
|
return adjustedPayload;
|
|
731
754
|
}
|
|
732
755
|
|
|
756
|
+
const controllingTraits = ["$doNotSend"] as const;
|
|
757
|
+
/**
|
|
758
|
+
* Remove all members of traits that controls identify/group behavior (see analytics.d.ts), and should not be recorded. Returns
|
|
759
|
+
* copy of the object with these members removed.
|
|
760
|
+
*
|
|
761
|
+
* Do not modify traits object, but creates one
|
|
762
|
+
* @param traits
|
|
763
|
+
*/
|
|
764
|
+
function stripControllingTraits(traits: Traits): Exclude<Traits, (typeof controllingTraits)[number]> {
|
|
765
|
+
const res = { ...traits };
|
|
766
|
+
// see Traits definition in analytics.d.ts. We cannot define const here, so here's a little code duplication
|
|
767
|
+
for (const key of controllingTraits) {
|
|
768
|
+
delete res[key];
|
|
769
|
+
}
|
|
770
|
+
return res;
|
|
771
|
+
}
|
|
772
|
+
|
|
733
773
|
export const jitsuAnalyticsPlugin = (jitsuOptions: JitsuOptions = {}, storage: PersistentStorage): AnalyticsPlugin => {
|
|
734
774
|
// just to make sure that all undefined values are replaced with defaultConfig values
|
|
735
775
|
mergeConfig(jitsuOptions, jitsuOptions);
|
|
@@ -792,9 +832,14 @@ export const jitsuAnalyticsPlugin = (jitsuOptions: JitsuOptions = {}, storage: P
|
|
|
792
832
|
}
|
|
793
833
|
// Store traits in cache to be able to use them in page and track events that run asynchronously with current identify.
|
|
794
834
|
storage.setItem("__user_id", payload.userId);
|
|
835
|
+
const doNotSend = payload.traits?.$doNotSend;
|
|
795
836
|
if (payload.traits && typeof payload.traits === "object") {
|
|
837
|
+
payload.traits = stripControllingTraits(payload.traits);
|
|
796
838
|
storage.setItem("__user_traits", payload.traits);
|
|
797
839
|
}
|
|
840
|
+
if (doNotSend) {
|
|
841
|
+
return Promise.resolve();
|
|
842
|
+
}
|
|
798
843
|
return send("identify", payload, config, instance, storage);
|
|
799
844
|
},
|
|
800
845
|
reset: args => {
|
|
@@ -838,9 +883,14 @@ export const jitsuAnalyticsPlugin = (jitsuOptions: JitsuOptions = {}, storage: P
|
|
|
838
883
|
const userId = options?.userId || user?.userId;
|
|
839
884
|
const anonymousId = options?.anonymousId || user?.anonymousId || storage.getItem("__anon_id");
|
|
840
885
|
storage.setItem("__group_id", groupId);
|
|
886
|
+
const doNotSend = traits?.$doNotSend;
|
|
841
887
|
if (traits && typeof traits === "object") {
|
|
888
|
+
traits = stripControllingTraits(traits);
|
|
842
889
|
storage.setItem("__group_traits", traits);
|
|
843
890
|
}
|
|
891
|
+
if (doNotSend) {
|
|
892
|
+
return Promise.resolve();
|
|
893
|
+
}
|
|
844
894
|
return send(
|
|
845
895
|
"group",
|
|
846
896
|
{ type: "group", groupId, traits, ...(anonymousId ? { anonymousId } : {}), ...(userId ? { userId } : {}) },
|