@jitsu/js 1.9.7-canary.903.20240731114701 → 1.9.8

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.
@@ -1,7 +1,16 @@
1
1
  /* global analytics */
2
2
 
3
- import { JitsuOptions, PersistentStorage, RuntimeFacade } from "./jitsu";
4
- import { AnalyticsClientEvent, Callback, ID, JSONObject, Options } from "@jitsu/protocols/analytics";
3
+ import {
4
+ DynamicJitsuOptions,
5
+ JitsuOptions,
6
+ PersistentStorage,
7
+ RuntimeFacade,
8
+ AnalyticsClientEvent,
9
+ Callback,
10
+ ID,
11
+ JSONObject,
12
+ Options,
13
+ } from "@jitsu/protocols/analytics";
5
14
  import parse from "./index";
6
15
 
7
16
  import { AnalyticsInstance, AnalyticsPlugin } from "analytics";
@@ -26,6 +35,39 @@ const defaultConfig: Required<JitsuOptions> = {
26
35
  fetchTimeoutMs: undefined,
27
36
  s2s: undefined,
28
37
  idEndpoint: undefined,
38
+ privacy: {
39
+ dontSend: false,
40
+ disableUserIds: false,
41
+ ipPolicy: "keep",
42
+ consentCategories: undefined,
43
+ },
44
+ };
45
+
46
+ // mergeConfig merges newConfig into currentConfig also making sure that all undefined values are replaced with defaultConfig values
47
+ const mergeConfig = (current: JitsuOptions, newConfig: JitsuOptions): void => {
48
+ for (const key of Object.keys(defaultConfig)) {
49
+ const value = newConfig[key];
50
+ if (key === "privacy") {
51
+ if (typeof value === "object") {
52
+ current.privacy = {
53
+ ...defaultConfig.privacy,
54
+ ...current.privacy,
55
+ ...value,
56
+ };
57
+ } else if (newConfig.hasOwnProperty("privacy") && typeof value === "undefined") {
58
+ // explicitly set to undefined - reset to default
59
+ current.privacy = { ...defaultConfig.privacy };
60
+ }
61
+ } else if (typeof value === "undefined") {
62
+ if (newConfig.hasOwnProperty(key) || !current.hasOwnProperty(key)) {
63
+ // explicitly set to undefined - reset to default
64
+ // or was not set at all - set to default
65
+ current[key] = defaultConfig[key];
66
+ }
67
+ } else {
68
+ current[key] = value;
69
+ }
70
+ }
29
71
  };
30
72
 
31
73
  export const parseQuery = (qs?: string): Record<string, string> => {
@@ -154,11 +196,20 @@ const defaultCookie2Key = {
154
196
  __anon_id: "__eventn_id",
155
197
  __user_traits: "__eventn_id_usr",
156
198
  __user_id: "__eventn_uid",
199
+ __group_id: "__group_id",
200
+ __group_traits: "__group_traits",
157
201
  };
158
202
 
159
203
  const cookieStorage: StorageFactory = (cookieDomain, key2cookie) => {
160
204
  return {
161
205
  setItem(key: string, val: any) {
206
+ if (typeof val === "undefined") {
207
+ removeCookie(key2cookie[key] || key, {
208
+ domain: cookieDomain,
209
+ secure: window.location.protocol === "https:",
210
+ });
211
+ return;
212
+ }
162
213
  const strVal = typeof val === "object" && val !== null ? encodeURIComponent(JSON.stringify(val)) : val;
163
214
  const cookieName = key2cookie[key] || key;
164
215
  setCookie(cookieName, strVal, {
@@ -270,7 +321,11 @@ export const emptyRuntime = (config: JitsuOptions): RuntimeFacade => ({
270
321
  if (config.debug) {
271
322
  console.log(`[JITSU EMPTY RUNTIME] Set storage item ${key}=${JSON.stringify(val)}`);
272
323
  }
273
- storage[key] = val;
324
+ if (typeof val === "undefined") {
325
+ delete storage[key];
326
+ } else {
327
+ storage[key] = val;
328
+ }
274
329
  },
275
330
  getItem(key: string) {
276
331
  const val = storage[key];
@@ -372,8 +427,13 @@ function adjustPayload(
372
427
  library: {
373
428
  name: jitsuLibraryName,
374
429
  version: jitsuVersion,
375
- env: s2s ? "node" : "browser",
430
+ env: isInBrowser() ? "browser" : "node",
376
431
  },
432
+ consent: config.privacy?.consentCategories
433
+ ? {
434
+ categoryPreferences: config.privacy.consentCategories,
435
+ }
436
+ : undefined,
377
437
  userAgent: runtime.userAgent(),
378
438
  locale: runtime.language(),
379
439
  screen: runtime.screen(),
@@ -388,11 +448,13 @@ function adjustPayload(
388
448
  url: properties.url || url,
389
449
  encoding: properties.encoding || runtime.documentEncoding(),
390
450
  },
391
- clientIds: {
392
- fbc: runtime.getCookie("_fbc"),
393
- fbp: runtime.getCookie("_fbp"),
394
- ...getGa4Ids(runtime),
395
- },
451
+ clientIds: !config.privacy?.disableUserIds
452
+ ? {
453
+ fbc: runtime.getCookie("_fbc"),
454
+ fbp: runtime.getCookie("_fbp"),
455
+ ...getGa4Ids(runtime),
456
+ }
457
+ : undefined,
396
458
  campaign: parseUtms(query),
397
459
  };
398
460
  const withContext = {
@@ -406,6 +468,12 @@ function adjustPayload(
406
468
  };
407
469
  delete withContext.meta;
408
470
  delete withContext.options;
471
+ if (config.privacy?.disableUserIds) {
472
+ delete withContext.userId;
473
+ delete withContext.anonymousId;
474
+ delete withContext.context.traits;
475
+ delete withContext.groupId;
476
+ }
409
477
  return withContext;
410
478
  }
411
479
 
@@ -562,7 +630,7 @@ function maskWriteKey(writeKey?: string): string | undefined {
562
630
  async function send(
563
631
  method,
564
632
  payload,
565
- jitsuConfig: Required<JitsuOptions>,
633
+ jitsuConfig: JitsuOptions,
566
634
  instance: AnalyticsInstance,
567
635
  store: PersistentStorage
568
636
  ): Promise<any> {
@@ -570,7 +638,7 @@ async function send(
570
638
  console.log(`[JITSU DEBUG] sending '${method}' event:`, payload);
571
639
  return;
572
640
  }
573
- const s2s = jitsuConfig.s2s === undefined ? !isInBrowser() : jitsuConfig.s2s;
641
+ const s2s = !!jitsuConfig.s2s;
574
642
  const url = s2s ? `${jitsuConfig.host}/api/s/s2s/${method}` : `${jitsuConfig.host}/api/s/${method}`;
575
643
  const fetch = jitsuConfig.fetch || globalThis.fetch;
576
644
  if (!fetch) {
@@ -592,15 +660,19 @@ async function send(
592
660
  : undefined;
593
661
 
594
662
  const authHeader = jitsuConfig.writeKey ? { "X-Write-Key": jitsuConfig.writeKey } : {};
663
+ const ipHeader =
664
+ typeof jitsuConfig.privacy?.ipPolicy === "undefined" || jitsuConfig.privacy?.ipPolicy === "keep"
665
+ ? {}
666
+ : { "X-IP-Policy": jitsuConfig.privacy.ipPolicy };
595
667
  let fetchResult;
596
668
  try {
597
669
  fetchResult = await fetch(url, {
598
670
  method: "POST",
599
671
  headers: {
600
672
  "Content-Type": "application/json",
601
-
602
673
  ...authHeader,
603
674
  ...debugHeader,
675
+ ...ipHeader,
604
676
  },
605
677
  body: JSON.stringify(adjustedPayload),
606
678
  signal: abortController?.signal,
@@ -658,17 +730,12 @@ async function send(
658
730
  return adjustedPayload;
659
731
  }
660
732
 
661
- export type JitsuPluginConfig = JitsuOptions & {
662
- storageWrapper?: (persistentStorage: PersistentStorage) => PersistentStorage;
663
- };
664
- export const jitsuAnalyticsPlugin = (pluginConfig: JitsuPluginConfig = {}): AnalyticsPlugin => {
665
- const instanceConfig = {
666
- ...defaultConfig,
667
- ...pluginConfig,
668
- };
733
+ export const jitsuAnalyticsPlugin = (jitsuOptions: JitsuOptions = {}, storage: PersistentStorage): AnalyticsPlugin => {
734
+ // just to make sure that all undefined values are replaced with defaultConfig values
735
+ mergeConfig(jitsuOptions, jitsuOptions);
669
736
  return {
670
737
  name: "jitsu",
671
- config: instanceConfig,
738
+ config: jitsuOptions,
672
739
 
673
740
  initialize: async args => {
674
741
  const { config } = args;
@@ -706,28 +773,24 @@ export const jitsuAnalyticsPlugin = (pluginConfig: JitsuPluginConfig = {}): Anal
706
773
  },
707
774
  page: args => {
708
775
  const { payload, config, instance } = args;
709
- return send(
710
- "page",
711
- payload,
712
- config,
713
- instance,
714
- pluginConfig.storageWrapper ? pluginConfig.storageWrapper(instance.storage) : instance.storage
715
- );
776
+ if (config.privacy?.dontSend) {
777
+ return;
778
+ }
779
+ return send("page", payload, config, instance, storage);
716
780
  },
717
781
  track: args => {
718
782
  const { payload, config, instance } = args;
719
- return send(
720
- "track",
721
- payload,
722
- config,
723
- instance,
724
- pluginConfig.storageWrapper ? pluginConfig.storageWrapper(instance.storage) : instance.storage
725
- );
783
+ if (config.privacy?.dontSend) {
784
+ return;
785
+ }
786
+ return send("track", payload, config, instance, storage);
726
787
  },
727
788
  identify: args => {
728
789
  const { payload, config, instance } = args;
790
+ if (config.privacy?.dontSend || config.privacy?.disableUserIds) {
791
+ return;
792
+ }
729
793
  // Store traits in cache to be able to use them in page and track events that run asynchronously with current identify.
730
- const storage = pluginConfig.storageWrapper ? pluginConfig.storageWrapper(instance.storage) : instance.storage;
731
794
  storage.setItem("__user_id", payload.userId);
732
795
  if (payload.traits && typeof payload.traits === "object") {
733
796
  storage.setItem("__user_traits", payload.traits);
@@ -736,37 +799,54 @@ export const jitsuAnalyticsPlugin = (pluginConfig: JitsuPluginConfig = {}): Anal
736
799
  },
737
800
  reset: args => {
738
801
  const { config, instance } = args;
739
- const storage = pluginConfig.storageWrapper ? pluginConfig.storageWrapper(instance.storage) : instance.storage;
740
- storage?.reset();
802
+ storage.reset();
741
803
  if (config.debug) {
742
804
  console.log("[JITSU DEBUG] Resetting Jitsu plugin storage");
743
805
  }
744
806
  },
745
807
  methods: {
746
808
  //analytics doesn't support group as a base method, so we need to add it manually
809
+ configure(newOptions: DynamicJitsuOptions) {
810
+ const idsWasDisabled = jitsuOptions.privacy?.disableUserIds || jitsuOptions.privacy?.dontSend;
811
+ mergeConfig(jitsuOptions, newOptions);
812
+ const idsDisabledNow = jitsuOptions.privacy?.disableUserIds || jitsuOptions.privacy?.dontSend;
813
+ if (!idsDisabledNow && idsWasDisabled) {
814
+ if (jitsuOptions.debug) {
815
+ console.log("[JITSU] Enabling Anonymous ID. Generating new Id.");
816
+ }
817
+ const instance = (this as any).instance;
818
+ const newAnonymousId = uuid();
819
+ const userState = instance.user();
820
+ if (userState) {
821
+ userState.anonymousId = newAnonymousId;
822
+ }
823
+ storage.setItem("__anon_id", newAnonymousId);
824
+ instance.setAnonymousId(newAnonymousId);
825
+ }
826
+ },
747
827
  group(groupId?: ID, traits?: JSONObject | null, options?: Options, callback?: Callback) {
828
+ if (jitsuOptions.privacy?.dontSend || jitsuOptions.privacy?.disableUserIds) {
829
+ return;
830
+ }
748
831
  if (typeof groupId === "number") {
749
832
  //fix potential issues with group id being used incorrectly
750
833
  groupId = groupId + "";
751
834
  }
752
835
 
753
- const analyticsInstance = this.instance;
754
- const cacheWrap = pluginConfig.storageWrapper
755
- ? pluginConfig.storageWrapper(analyticsInstance.storage)
756
- : analyticsInstance.storage;
757
- const user = analyticsInstance.user();
836
+ const instance = (this as any).instance;
837
+ const user = instance.user();
758
838
  const userId = options?.userId || user?.userId;
759
- const anonymousId = options?.anonymousId || user?.anonymousId || cacheWrap.getItem("__anon_id");
760
- cacheWrap.setItem("__group_id", groupId);
839
+ const anonymousId = options?.anonymousId || user?.anonymousId || storage.getItem("__anon_id");
840
+ storage.setItem("__group_id", groupId);
761
841
  if (traits && typeof traits === "object") {
762
- cacheWrap.setItem("__group_traits", traits);
842
+ storage.setItem("__group_traits", traits);
763
843
  }
764
844
  return send(
765
845
  "group",
766
846
  { type: "group", groupId, traits, ...(anonymousId ? { anonymousId } : {}), ...(userId ? { userId } : {}) },
767
- instanceConfig,
768
- analyticsInstance,
769
- cacheWrap
847
+ jitsuOptions,
848
+ instance,
849
+ storage
770
850
  );
771
851
  },
772
852
  },
@@ -786,6 +866,23 @@ export function randomId(hashString: string | undefined = ""): string {
786
866
  );
787
867
  }
788
868
 
869
+ export function uuid() {
870
+ var u = "",
871
+ m = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx",
872
+ i = 0,
873
+ rb = (Math.random() * 0xffffffff) | 0;
874
+
875
+ while (i++ < 36) {
876
+ var c = m[i - 1],
877
+ r = rb & 0xf,
878
+ v = c == "x" ? r : (r & 0x3) | 0x8;
879
+
880
+ u += c == "-" || c == "4" ? c : v.toString(16);
881
+ rb = i % 8 == 0 ? (Math.random() * 0xffffffff) | 0 : rb >> 4;
882
+ }
883
+ return u;
884
+ }
885
+
789
886
  function hash(str: string, seed: number = 0): number {
790
887
  let h1 = 0xdeadbeef ^ seed,
791
888
  h2 = 0x41c6ce57 ^ seed;
package/src/browser.ts CHANGED
@@ -1,9 +1,8 @@
1
- import type { AnalyticsInterface, JitsuOptions } from "./jitsu";
1
+ import type { AnalyticsInterface, JitsuOptions } from "@jitsu/protocols/analytics";
2
2
  import { jitsuAnalytics } from "./index";
3
3
 
4
4
  export type JitsuBrowserOptions = {
5
5
  namespace?: string;
6
- userId?: string;
7
6
  onload?: string;
8
7
  initOnly?: boolean;
9
8
  } & JitsuOptions;
@@ -14,16 +13,47 @@ function snakeToCamel(s: string) {
14
13
  });
15
14
  }
16
15
 
17
- export type Parser = (arg: string) => any;
18
- const booleanParser = (arg: string) => arg === "true" || arg === "1" || arg === "yes";
16
+ export type Parser = {
17
+ path?: (name: string) => string[];
18
+ parse: (arg: string) => any;
19
+ };
20
+ const trimPrefix = (s: string, prefix: string) => s.replace(new RegExp(`^${prefix}`), "");
21
+
22
+ const defaultParser = (nestedPath: string[] = []) => ({
23
+ path: (name: string) => [
24
+ ...nestedPath,
25
+ snakeToCamel(nestedPath.length > 0 ? trimPrefix(name, nestedPath.join("-") + "-") : name),
26
+ ],
27
+ parse: (arg: string) => arg,
28
+ });
29
+
30
+ const booleanParser = (nestedPath: string[] = []) => ({
31
+ ...defaultParser(nestedPath),
32
+ parse: (arg: string) => arg === "true" || arg === "1" || arg === "yes",
33
+ });
19
34
 
20
- const parsers: Partial<Record<keyof JitsuBrowserOptions, Parser>> = {
21
- debug: booleanParser,
22
- initOnly: booleanParser,
35
+ const parsers: Partial<Record<string, Parser>> = {
36
+ debug: booleanParser(),
37
+ "privacy-disable-user-ids": booleanParser(["privacy"]),
38
+ "privacy-dont-send": booleanParser(["privacy"]),
39
+ "privacy-ip-policy": defaultParser(["privacy"]),
40
+ "echo-events": booleanParser(),
41
+ "init-only": booleanParser(),
23
42
  };
24
43
 
25
- function getParser(name: keyof JitsuBrowserOptions): Parser {
26
- return parsers[name] || (x => x);
44
+ function getParser(name: string): Parser {
45
+ return parsers[name] || defaultParser();
46
+ }
47
+
48
+ function setPath(obj: any, path: string[], value: any) {
49
+ let current = obj;
50
+ let i = 0;
51
+ for (; i < path.length - 1; i++) {
52
+ const key = path[i];
53
+ current[key] = current[key] || {};
54
+ current = current[key];
55
+ }
56
+ current[path[i]] = value;
27
57
  }
28
58
 
29
59
  function getScriptAttributes(scriptElement: HTMLScriptElement) {
@@ -31,13 +61,12 @@ function getScriptAttributes(scriptElement: HTMLScriptElement) {
31
61
  .getAttributeNames()
32
62
  .filter(name => name.indexOf("data-") === 0)
33
63
  .map(name => name.substring("data-".length))
34
- .reduce(
35
- (res, name) => ({
36
- ...res,
37
- [snakeToCamel(name)]: getParser(snakeToCamel(name) as any)(scriptElement.getAttribute(`data-${name}`)),
38
- }),
39
- {}
40
- );
64
+ .reduce((res, name) => {
65
+ const parser = getParser(name);
66
+ const path = parser.path(name);
67
+ setPath(res, path, parser.parse(scriptElement.getAttribute(`data-${name}`)));
68
+ return res;
69
+ }, {});
41
70
  }
42
71
 
43
72
  function runCallback(callback: any, jitsu: AnalyticsInterface) {
@@ -3,7 +3,6 @@ import { tagPlugin } from "./tag";
3
3
  import { logrocketPlugin } from "./logrocket";
4
4
  import { gtmPlugin } from "./gtm";
5
5
  import { ga4Plugin } from "./ga4";
6
- import type { JitsuOptions } from "../jitsu";
7
6
 
8
7
  export type InternalPlugin<T> = {
9
8
  id: string;
package/src/index.ts CHANGED
@@ -1,7 +1,17 @@
1
1
  import Analytics from "analytics";
2
- import { AnalyticsInterface, JitsuOptions, PersistentStorage, RuntimeFacade } from "./jitsu";
3
- import { jitsuAnalyticsPlugin, emptyRuntime, isInBrowser, windowRuntime } from "./analytics-plugin";
4
- import { Callback, DispatchedEvent, ID, JSONObject, Options } from "@jitsu/protocols/analytics";
2
+ import { jitsuAnalyticsPlugin, emptyRuntime, isInBrowser, windowRuntime, uuid } from "./analytics-plugin";
3
+ import {
4
+ Callback,
5
+ DispatchedEvent,
6
+ ID,
7
+ JSONObject,
8
+ Options,
9
+ AnalyticsInterface,
10
+ JitsuOptions,
11
+ PersistentStorage,
12
+ RuntimeFacade,
13
+ DynamicJitsuOptions,
14
+ } from "@jitsu/protocols/analytics";
5
15
 
6
16
  export default function parse(input) {
7
17
  let value = input;
@@ -31,6 +41,7 @@ export const emptyAnalytics: AnalyticsInterface = {
31
41
  identify: () => Promise.resolve({}),
32
42
  group: () => Promise.resolve({}),
33
43
  reset: () => Promise.resolve({}),
44
+ configure: () => {},
34
45
  };
35
46
 
36
47
  function createUnderlyingAnalyticsInstance(
@@ -38,8 +49,6 @@ function createUnderlyingAnalyticsInstance(
38
49
  rt: RuntimeFacade,
39
50
  plugins: any[] = []
40
51
  ): AnalyticsInterface {
41
- const storage = rt.store();
42
-
43
52
  const storageCache: any = {};
44
53
 
45
54
  // AnalyticsInstance's storage is async somewhere inside. So if we make 'page' call right after 'identify' call
@@ -47,6 +56,9 @@ function createUnderlyingAnalyticsInstance(
47
56
  // to avoid that we use in-memory cache for storage
48
57
  const cachingStorageWrapper = (persistentStorage: PersistentStorage) => ({
49
58
  setItem(key: string, val: any) {
59
+ if (opts.privacy?.dontSend || opts.privacy?.disableUserIds) {
60
+ return;
61
+ }
50
62
  if (opts.debug) {
51
63
  console.log(`[JITSU DEBUG] Caching storage setItem: ${key}=${val}`);
52
64
  }
@@ -54,6 +66,9 @@ function createUnderlyingAnalyticsInstance(
54
66
  persistentStorage.setItem(key, val);
55
67
  },
56
68
  getItem(key: string) {
69
+ if (opts.privacy?.dontSend || opts.privacy?.disableUserIds) {
70
+ return;
71
+ }
57
72
  const value = storageCache[key] || persistentStorage.getItem(key);
58
73
  if (opts.debug) {
59
74
  console.log(
@@ -66,7 +81,7 @@ function createUnderlyingAnalyticsInstance(
66
81
  for (const key of [...Object.keys(storageCache)]) {
67
82
  delete storageCache[key];
68
83
  }
69
- storage.reset();
84
+ persistentStorage.reset();
70
85
  },
71
86
  removeItem(key: string) {
72
87
  if (opts.debug) {
@@ -76,14 +91,15 @@ function createUnderlyingAnalyticsInstance(
76
91
  persistentStorage.removeItem(key);
77
92
  },
78
93
  });
94
+ const storage = cachingStorageWrapper(rt.store());
79
95
 
80
96
  const analytics = Analytics({
81
97
  debug: !!opts.debug,
82
98
  storage,
83
- plugins: [jitsuAnalyticsPlugin({ ...opts, storageWrapper: cachingStorageWrapper }), ...plugins],
99
+ plugins: [jitsuAnalyticsPlugin(opts, storage), ...plugins],
84
100
  } as any);
85
101
 
86
- return {
102
+ const a = {
87
103
  ...analytics,
88
104
  page: (...args) => {
89
105
  if (args.length === 2 && typeof args[0] === "string" && typeof args[1] === "object") {
@@ -124,7 +140,7 @@ function createUnderlyingAnalyticsInstance(
124
140
  if (opts.debug) {
125
141
  console.log("[JITSU DEBUG] Setting anonymous id to " + id);
126
142
  }
127
- //Workaround for analytics.js bug. Underlying setAnonymousId doesn't work set the id immediately,
143
+ //Workaround for analytics.js bug. Underlying setAnonymousId doesn't set the id immediately,
128
144
  //so we got to it manually here. See https://github.com/jitsucom/jitsu/issues/1060
129
145
  storage.setItem("__anon_id", id);
130
146
  const userState = analytics.user();
@@ -144,6 +160,19 @@ function createUnderlyingAnalyticsInstance(
144
160
  console.log("[JITSU DEBUG] User state after reset", JSON.stringify(analytics.user()));
145
161
  }
146
162
  },
163
+ async configure(options: DynamicJitsuOptions) {
164
+ if (opts.debug) {
165
+ console.log("[JITSU DEBUG] Update Jitsu config with", JSON.stringify(options));
166
+ }
167
+ if (options.privacy?.disableUserIds || options.privacy?.dontSend) {
168
+ storage.reset();
169
+ }
170
+ for (const plugin of Object.values(analytics.plugins)) {
171
+ if (typeof plugin["configure"] === "function") {
172
+ plugin["configure"](options);
173
+ }
174
+ }
175
+ },
147
176
  async group(
148
177
  groupId?: ID,
149
178
  traits?: JSONObject | null,
@@ -161,6 +190,10 @@ function createUnderlyingAnalyticsInstance(
161
190
  return results[0];
162
191
  },
163
192
  } as AnalyticsInterface;
193
+ if (opts.privacy?.disableUserIds || opts.privacy?.dontSend) {
194
+ storage.reset();
195
+ }
196
+ return a;
164
197
  }
165
198
 
166
199
  /**
@@ -171,7 +204,9 @@ function fixOptions(opts: JitsuOptions): JitsuOptions {
171
204
  return {
172
205
  ...opts,
173
206
  host:
174
- opts.host.indexOf("https://") !== 0 && opts.host.indexOf("http://") !== 0 ? `https://${opts.host}` : opts.host,
207
+ (opts.host ?? "").indexOf("https://") !== 0 && (opts.host ?? "").indexOf("http://") !== 0
208
+ ? `https://${opts.host}`
209
+ : opts.host,
175
210
  };
176
211
  }
177
212
 
@@ -205,22 +240,16 @@ export function jitsuAnalytics(_opts: JitsuOptions): AnalyticsInterface {
205
240
  // }
206
241
  }
207
242
 
208
- function uuid() {
209
- var u = "",
210
- m = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx",
211
- i = 0,
212
- rb = (Math.random() * 0xffffffff) | 0;
213
-
214
- while (i++ < 36) {
215
- var c = m[i - 1],
216
- r = rb & 0xf,
217
- v = c == "x" ? r : (r & 0x3) | 0x8;
218
-
219
- u += c == "-" || c == "4" ? c : v.toString(16);
220
- rb = i % 8 == 0 ? (Math.random() * 0xffffffff) | 0 : rb >> 4;
221
- }
222
- return u;
223
- }
224
-
225
- export * from "./jitsu";
243
+ export {
244
+ Callback,
245
+ DispatchedEvent,
246
+ ID,
247
+ JSONObject,
248
+ Options,
249
+ AnalyticsInterface,
250
+ JitsuOptions,
251
+ PersistentStorage,
252
+ RuntimeFacade,
253
+ DynamicJitsuOptions,
254
+ };
226
255
  export * from "./analytics-plugin";
package/src/jitsu.ts DELETED
@@ -1,93 +0,0 @@
1
- import type { AnalyticsInterface } from "@jitsu/protocols/analytics";
2
-
3
- type JitsuOptions = {
4
- /**
5
- * API Key. Optional. If not set, Jitsu will send event to the server without auth, and server
6
- * will link the call to configured source by domain name
7
- */
8
- writeKey?: string;
9
- /**
10
- * API Host. Default value: same host as script origin
11
- */
12
- host?: string;
13
- /**
14
- * To enable debug logging
15
- */
16
- debug?: boolean;
17
- /**
18
- * Explicitly specify cookie domain. If not set, cookie domain will be set to top level
19
- * of the current domain. Example: if JS lives on "app.example.com", cookie domain will be
20
- * set to ".example.com". If it lives on "example.com", cookie domain will be set to ".example.com" too
21
- */
22
- cookieDomain?: string;
23
- /**
24
- * Provide fetch implementation. It is required if you want to use Jitsu in NodeJS
25
- */
26
- fetch?: typeof fetch;
27
- /**
28
- * Which runtime to use. Runtime is used for obtaining context of the event: cookes,
29
- * url, etc. At the moment, Jitsu supports browser runtime and NodeJS runtime, but you
30
- * can provide your own implementation.
31
- *
32
- * If it's not set, the runtime will be detected automatically by presense of `window` object
33
- */
34
- runtime?: RuntimeFacade;
35
- /**
36
- * If set to true, jitsu will output events in console. In this case you don't need to set
37
- * writeKey / host. It's useful for debugging development environment
38
- */
39
- echoEvents?: boolean;
40
-
41
- /**
42
- * If true, events will go to s2s endpoints like ${host}/api/s/s2s/{type}. Otherwise they'll go to ${host}/api/s/{type}.
43
- *
44
- * If not set at all, it will be detected automatically by presence of `window` object
45
- */
46
- s2s?: boolean;
47
-
48
- /**
49
- * Timeout for fetch requests. Default value: 5000
50
- */
51
- fetchTimeoutMs?: number;
52
-
53
- /**
54
- * Endpoint that makes sure that Jitsu anonymousId cookie is set as server (httpOnly) cookie.
55
- * Endpoint must be hosted on the same domain as the site where Jitsu code is installed.
56
- * Required to overcome Safari ITP restrictions.
57
- */
58
- idEndpoint?: string;
59
- };
60
-
61
- type PersistentStorage = {
62
- getItem: (key: string, options?: any) => any;
63
- setItem: (key: string, value: any, options?: any) => void;
64
- removeItem: (key: string, options?: any) => void;
65
- reset: () => void;
66
- };
67
-
68
- type RuntimeFacade = {
69
- store(): PersistentStorage;
70
- userAgent(): string | undefined;
71
- language(): string | undefined;
72
- pageUrl(): string | undefined;
73
- documentEncoding(): string | undefined;
74
- getCookie(name: string): string | undefined;
75
- getCookies(): Record<string, string>;
76
-
77
- timezoneOffset(): number | undefined;
78
- screen():
79
- | {
80
- width: number;
81
- height: number;
82
- innerWidth: number;
83
- innerHeight: number;
84
- density: number;
85
- }
86
- | undefined;
87
- referrer(): string | undefined;
88
- pageTitle(): string | undefined;
89
- };
90
-
91
- export declare function jitsuAnalytics(opts: JitsuOptions): AnalyticsInterface;
92
-
93
- export { AnalyticsInterface, JitsuOptions, PersistentStorage, RuntimeFacade };