@jitsu/js 1.9.0 → 1.9.1

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/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { AnalyticsInterface, JitsuOptions } from "./jitsu";
2
2
  export default function parse(input: any): any;
3
3
  export declare const emptyAnalytics: AnalyticsInterface;
4
- export declare function jitsuAnalytics(opts: JitsuOptions): AnalyticsInterface;
4
+ export declare function jitsuAnalytics(_opts: JitsuOptions): AnalyticsInterface;
5
5
  export * from "./jitsu";
6
6
  export * from "./analytics-plugin";
package/dist/jitsu.cjs.js CHANGED
@@ -280,32 +280,67 @@ var __awaiter$3 = (undefined && undefined.__awaiter) || function (thisArg, _argu
280
280
  step((generator = generator.apply(thisArg, _arguments || [])).next());
281
281
  });
282
282
  };
283
+ function omit(obj, ...keys) {
284
+ return Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));
285
+ }
283
286
  const gtmPlugin = {
284
287
  id: "gtm",
285
288
  handle(config, payload) {
286
- var _a, _b;
289
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
287
290
  return __awaiter$3(this, void 0, void 0, function* () {
291
+ const debug = !!config.debug;
288
292
  if (!applyFilters(payload, config)) {
289
293
  return;
290
294
  }
291
295
  yield initGtmIfNeeded(config, payload);
292
296
  const dataLayer = window[config.dataLayerName || "dataLayer"];
293
- const ids = Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId, userId: payload.userId } : {})), (payload.anonymousId ? { anonymousId: payload.anonymousId } : {}));
297
+ //traits could be in both nodes, context.traits takes precedence
298
+ const traits = Object.assign(Object.assign({}, ((payload === null || payload === void 0 ? void 0 : payload.traits) || {})), (((_a = payload === null || payload === void 0 ? void 0 : payload.context) === null || _a === void 0 ? void 0 : _a.traits) || {}));
299
+ //remove properties that defined separately
300
+ const idsFromTraits = omit(traits, "id", "userId", "user_id", "anonymousId", "userId");
301
+ if (debug) {
302
+ console.debug("GTM plugin will be applied to following payload", payload);
303
+ }
304
+ // See https://developers.google.com/tag-platform/tag-manager/server-side/common-event-data
305
+ const userData = {
306
+ email_address: traits.email,
307
+ };
308
+ const ids = Object.assign(Object.assign(Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId, userId: payload.userId } : {})), (payload.anonymousId ? { anonymousId: payload.anonymousId } : {})), idsFromTraits), { user_data: Object.keys(userData).length > 0 ? userData : undefined });
309
+ if (debug) {
310
+ console.debug("GTM plugin will set following user-related data layer vars", ids);
311
+ }
312
+ const pageProperties = payload.properties || {};
313
+ const pageVariables = {
314
+ page_location: pageProperties.url || ((_c = (_b = payload.context) === null || _b === void 0 ? void 0 : _b.page) === null || _c === void 0 ? void 0 : _c.url),
315
+ page_title: pageProperties.title || ((_e = (_d = payload.context) === null || _d === void 0 ? void 0 : _d.page) === null || _e === void 0 ? void 0 : _e.title),
316
+ page_path: pageProperties.path || ((_g = (_f = payload.context) === null || _f === void 0 ? void 0 : _f.page) === null || _g === void 0 ? void 0 : _g.path),
317
+ page_hash: pageProperties.hash || ((_j = (_h = payload.context) === null || _h === void 0 ? void 0 : _h.page) === null || _j === void 0 ? void 0 : _j.hash),
318
+ page_search: pageProperties.search || ((_l = (_k = payload.context) === null || _k === void 0 ? void 0 : _k.page) === null || _l === void 0 ? void 0 : _l.search),
319
+ page_referrer: (_p = (_o = (_m = payload === null || payload === void 0 ? void 0 : payload.context) === null || _m === void 0 ? void 0 : _m.page) === null || _o === void 0 ? void 0 : _o.referrer) !== null && _p !== void 0 ? _p : "",
320
+ };
321
+ if (debug) {
322
+ console.debug("GTM plugin will set following context (page) related data layer vars", ids);
323
+ }
324
+ const pushToDataLayer = (data) => {
325
+ dataLayer.push(data);
326
+ if (debug) {
327
+ console.debug("GTM plugin will push following data to dataLayer", data);
328
+ }
329
+ };
294
330
  switch (payload.type) {
295
331
  case "page":
296
- const { properties: pageProperties, context } = payload;
297
- const pageEvent = Object.assign({ event: "page_view", page_location: pageProperties.url, page_title: pageProperties.title, page_path: pageProperties.path, page_hash: pageProperties.hash, page_search: pageProperties.search, page_referrer: (_b = (_a = context === null || context === void 0 ? void 0 : context.page) === null || _a === void 0 ? void 0 : _a.referrer) !== null && _b !== void 0 ? _b : "" }, ids);
298
- dataLayer.push(pageEvent);
332
+ const pageEvent = Object.assign(Object.assign({ event: "page_view" }, pageVariables), ids);
333
+ pushToDataLayer(pageEvent);
299
334
  break;
300
335
  case "track":
301
336
  const { properties: trackProperties } = payload;
302
- const trackEvent = Object.assign(Object.assign({ event: payload.event }, trackProperties), ids);
303
- dataLayer.push(trackEvent);
337
+ const trackEvent = Object.assign(Object.assign(Object.assign({ event: payload.event }, pageVariables), trackProperties), ids);
338
+ pushToDataLayer(trackEvent);
304
339
  break;
305
340
  case "identify":
306
341
  const { traits } = payload;
307
- const identifyEvent = Object.assign(Object.assign({ event: "identify" }, traits), ids);
308
- dataLayer.push(identifyEvent);
342
+ const identifyEvent = Object.assign(Object.assign(Object.assign({ event: "identify" }, pageVariables), traits), ids);
343
+ pushToDataLayer(identifyEvent);
309
344
  break;
310
345
  }
311
346
  dataLayer.push(function () {
@@ -1314,7 +1349,7 @@ function processDestinations(destinations, method, originalEvent, debug, analyti
1314
1349
  if (plugin) {
1315
1350
  for (const event of newEvents) {
1316
1351
  try {
1317
- promises.push(plugin.handle(credentials, event));
1352
+ promises.push(plugin.handle(Object.assign(Object.assign({}, credentials), { debug: true }), event));
1318
1353
  }
1319
1354
  catch (e) {
1320
1355
  console.warn(`[JITSU] Error processing event with internal plugin '${destination.deviceOptions.name}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
@@ -1686,7 +1721,15 @@ function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
1686
1721
  });
1687
1722
  } });
1688
1723
  }
1689
- function jitsuAnalytics(opts) {
1724
+ /**
1725
+ * Fix common mistakes in jitsu configuration
1726
+ * @param opts
1727
+ */
1728
+ function fixOptions(opts) {
1729
+ return Object.assign(Object.assign({}, opts), { host: opts.host.indexOf("https://") !== 0 && opts.host.indexOf("http://") !== 0 ? `https://${opts.host}` : opts.host });
1730
+ }
1731
+ function jitsuAnalytics(_opts) {
1732
+ const opts = fixOptions(_opts);
1690
1733
  const inBrowser = isInBrowser();
1691
1734
  const rt = opts.runtime || (inBrowser ? windowRuntime(opts) : emptyRuntime(opts));
1692
1735
  return createUnderlyingAnalyticsInstance(opts, rt);
package/dist/jitsu.es.js CHANGED
@@ -278,32 +278,67 @@ var __awaiter$3 = (undefined && undefined.__awaiter) || function (thisArg, _argu
278
278
  step((generator = generator.apply(thisArg, _arguments || [])).next());
279
279
  });
280
280
  };
281
+ function omit(obj, ...keys) {
282
+ return Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));
283
+ }
281
284
  const gtmPlugin = {
282
285
  id: "gtm",
283
286
  handle(config, payload) {
284
- var _a, _b;
287
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
285
288
  return __awaiter$3(this, void 0, void 0, function* () {
289
+ const debug = !!config.debug;
286
290
  if (!applyFilters(payload, config)) {
287
291
  return;
288
292
  }
289
293
  yield initGtmIfNeeded(config, payload);
290
294
  const dataLayer = window[config.dataLayerName || "dataLayer"];
291
- const ids = Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId, userId: payload.userId } : {})), (payload.anonymousId ? { anonymousId: payload.anonymousId } : {}));
295
+ //traits could be in both nodes, context.traits takes precedence
296
+ const traits = Object.assign(Object.assign({}, ((payload === null || payload === void 0 ? void 0 : payload.traits) || {})), (((_a = payload === null || payload === void 0 ? void 0 : payload.context) === null || _a === void 0 ? void 0 : _a.traits) || {}));
297
+ //remove properties that defined separately
298
+ const idsFromTraits = omit(traits, "id", "userId", "user_id", "anonymousId", "userId");
299
+ if (debug) {
300
+ console.debug("GTM plugin will be applied to following payload", payload);
301
+ }
302
+ // See https://developers.google.com/tag-platform/tag-manager/server-side/common-event-data
303
+ const userData = {
304
+ email_address: traits.email,
305
+ };
306
+ const ids = Object.assign(Object.assign(Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId, userId: payload.userId } : {})), (payload.anonymousId ? { anonymousId: payload.anonymousId } : {})), idsFromTraits), { user_data: Object.keys(userData).length > 0 ? userData : undefined });
307
+ if (debug) {
308
+ console.debug("GTM plugin will set following user-related data layer vars", ids);
309
+ }
310
+ const pageProperties = payload.properties || {};
311
+ const pageVariables = {
312
+ page_location: pageProperties.url || ((_c = (_b = payload.context) === null || _b === void 0 ? void 0 : _b.page) === null || _c === void 0 ? void 0 : _c.url),
313
+ page_title: pageProperties.title || ((_e = (_d = payload.context) === null || _d === void 0 ? void 0 : _d.page) === null || _e === void 0 ? void 0 : _e.title),
314
+ page_path: pageProperties.path || ((_g = (_f = payload.context) === null || _f === void 0 ? void 0 : _f.page) === null || _g === void 0 ? void 0 : _g.path),
315
+ page_hash: pageProperties.hash || ((_j = (_h = payload.context) === null || _h === void 0 ? void 0 : _h.page) === null || _j === void 0 ? void 0 : _j.hash),
316
+ page_search: pageProperties.search || ((_l = (_k = payload.context) === null || _k === void 0 ? void 0 : _k.page) === null || _l === void 0 ? void 0 : _l.search),
317
+ page_referrer: (_p = (_o = (_m = payload === null || payload === void 0 ? void 0 : payload.context) === null || _m === void 0 ? void 0 : _m.page) === null || _o === void 0 ? void 0 : _o.referrer) !== null && _p !== void 0 ? _p : "",
318
+ };
319
+ if (debug) {
320
+ console.debug("GTM plugin will set following context (page) related data layer vars", ids);
321
+ }
322
+ const pushToDataLayer = (data) => {
323
+ dataLayer.push(data);
324
+ if (debug) {
325
+ console.debug("GTM plugin will push following data to dataLayer", data);
326
+ }
327
+ };
292
328
  switch (payload.type) {
293
329
  case "page":
294
- const { properties: pageProperties, context } = payload;
295
- const pageEvent = Object.assign({ event: "page_view", page_location: pageProperties.url, page_title: pageProperties.title, page_path: pageProperties.path, page_hash: pageProperties.hash, page_search: pageProperties.search, page_referrer: (_b = (_a = context === null || context === void 0 ? void 0 : context.page) === null || _a === void 0 ? void 0 : _a.referrer) !== null && _b !== void 0 ? _b : "" }, ids);
296
- dataLayer.push(pageEvent);
330
+ const pageEvent = Object.assign(Object.assign({ event: "page_view" }, pageVariables), ids);
331
+ pushToDataLayer(pageEvent);
297
332
  break;
298
333
  case "track":
299
334
  const { properties: trackProperties } = payload;
300
- const trackEvent = Object.assign(Object.assign({ event: payload.event }, trackProperties), ids);
301
- dataLayer.push(trackEvent);
335
+ const trackEvent = Object.assign(Object.assign(Object.assign({ event: payload.event }, pageVariables), trackProperties), ids);
336
+ pushToDataLayer(trackEvent);
302
337
  break;
303
338
  case "identify":
304
339
  const { traits } = payload;
305
- const identifyEvent = Object.assign(Object.assign({ event: "identify" }, traits), ids);
306
- dataLayer.push(identifyEvent);
340
+ const identifyEvent = Object.assign(Object.assign(Object.assign({ event: "identify" }, pageVariables), traits), ids);
341
+ pushToDataLayer(identifyEvent);
307
342
  break;
308
343
  }
309
344
  dataLayer.push(function () {
@@ -1312,7 +1347,7 @@ function processDestinations(destinations, method, originalEvent, debug, analyti
1312
1347
  if (plugin) {
1313
1348
  for (const event of newEvents) {
1314
1349
  try {
1315
- promises.push(plugin.handle(credentials, event));
1350
+ promises.push(plugin.handle(Object.assign(Object.assign({}, credentials), { debug: true }), event));
1316
1351
  }
1317
1352
  catch (e) {
1318
1353
  console.warn(`[JITSU] Error processing event with internal plugin '${destination.deviceOptions.name}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
@@ -1684,7 +1719,15 @@ function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
1684
1719
  });
1685
1720
  } });
1686
1721
  }
1687
- function jitsuAnalytics(opts) {
1722
+ /**
1723
+ * Fix common mistakes in jitsu configuration
1724
+ * @param opts
1725
+ */
1726
+ function fixOptions(opts) {
1727
+ return Object.assign(Object.assign({}, opts), { host: opts.host.indexOf("https://") !== 0 && opts.host.indexOf("http://") !== 0 ? `https://${opts.host}` : opts.host });
1728
+ }
1729
+ function jitsuAnalytics(_opts) {
1730
+ const opts = fixOptions(_opts);
1688
1731
  const inBrowser = isInBrowser();
1689
1732
  const rt = opts.runtime || (inBrowser ? windowRuntime(opts) : emptyRuntime(opts));
1690
1733
  return createUnderlyingAnalyticsInstance(opts, rt);
package/dist/web/p.js.txt CHANGED
@@ -281,32 +281,67 @@
281
281
  step((generator = generator.apply(thisArg, _arguments || [])).next());
282
282
  });
283
283
  };
284
+ function omit(obj, ...keys) {
285
+ return Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));
286
+ }
284
287
  const gtmPlugin = {
285
288
  id: "gtm",
286
289
  handle(config, payload) {
287
- var _a, _b;
290
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
288
291
  return __awaiter$3(this, void 0, void 0, function* () {
292
+ const debug = !!config.debug;
289
293
  if (!applyFilters(payload, config)) {
290
294
  return;
291
295
  }
292
296
  yield initGtmIfNeeded(config, payload);
293
297
  const dataLayer = window[config.dataLayerName || "dataLayer"];
294
- const ids = Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId, userId: payload.userId } : {})), (payload.anonymousId ? { anonymousId: payload.anonymousId } : {}));
298
+ //traits could be in both nodes, context.traits takes precedence
299
+ const traits = Object.assign(Object.assign({}, ((payload === null || payload === void 0 ? void 0 : payload.traits) || {})), (((_a = payload === null || payload === void 0 ? void 0 : payload.context) === null || _a === void 0 ? void 0 : _a.traits) || {}));
300
+ //remove properties that defined separately
301
+ const idsFromTraits = omit(traits, "id", "userId", "user_id", "anonymousId", "userId");
302
+ if (debug) {
303
+ console.debug("GTM plugin will be applied to following payload", payload);
304
+ }
305
+ // See https://developers.google.com/tag-platform/tag-manager/server-side/common-event-data
306
+ const userData = {
307
+ email_address: traits.email,
308
+ };
309
+ const ids = Object.assign(Object.assign(Object.assign(Object.assign({}, (payload.userId ? { user_id: payload.userId, userId: payload.userId } : {})), (payload.anonymousId ? { anonymousId: payload.anonymousId } : {})), idsFromTraits), { user_data: Object.keys(userData).length > 0 ? userData : undefined });
310
+ if (debug) {
311
+ console.debug("GTM plugin will set following user-related data layer vars", ids);
312
+ }
313
+ const pageProperties = payload.properties || {};
314
+ const pageVariables = {
315
+ page_location: pageProperties.url || ((_c = (_b = payload.context) === null || _b === void 0 ? void 0 : _b.page) === null || _c === void 0 ? void 0 : _c.url),
316
+ page_title: pageProperties.title || ((_e = (_d = payload.context) === null || _d === void 0 ? void 0 : _d.page) === null || _e === void 0 ? void 0 : _e.title),
317
+ page_path: pageProperties.path || ((_g = (_f = payload.context) === null || _f === void 0 ? void 0 : _f.page) === null || _g === void 0 ? void 0 : _g.path),
318
+ page_hash: pageProperties.hash || ((_j = (_h = payload.context) === null || _h === void 0 ? void 0 : _h.page) === null || _j === void 0 ? void 0 : _j.hash),
319
+ page_search: pageProperties.search || ((_l = (_k = payload.context) === null || _k === void 0 ? void 0 : _k.page) === null || _l === void 0 ? void 0 : _l.search),
320
+ page_referrer: (_p = (_o = (_m = payload === null || payload === void 0 ? void 0 : payload.context) === null || _m === void 0 ? void 0 : _m.page) === null || _o === void 0 ? void 0 : _o.referrer) !== null && _p !== void 0 ? _p : "",
321
+ };
322
+ if (debug) {
323
+ console.debug("GTM plugin will set following context (page) related data layer vars", ids);
324
+ }
325
+ const pushToDataLayer = (data) => {
326
+ dataLayer.push(data);
327
+ if (debug) {
328
+ console.debug("GTM plugin will push following data to dataLayer", data);
329
+ }
330
+ };
295
331
  switch (payload.type) {
296
332
  case "page":
297
- const { properties: pageProperties, context } = payload;
298
- const pageEvent = Object.assign({ event: "page_view", page_location: pageProperties.url, page_title: pageProperties.title, page_path: pageProperties.path, page_hash: pageProperties.hash, page_search: pageProperties.search, page_referrer: (_b = (_a = context === null || context === void 0 ? void 0 : context.page) === null || _a === void 0 ? void 0 : _a.referrer) !== null && _b !== void 0 ? _b : "" }, ids);
299
- dataLayer.push(pageEvent);
333
+ const pageEvent = Object.assign(Object.assign({ event: "page_view" }, pageVariables), ids);
334
+ pushToDataLayer(pageEvent);
300
335
  break;
301
336
  case "track":
302
337
  const { properties: trackProperties } = payload;
303
- const trackEvent = Object.assign(Object.assign({ event: payload.event }, trackProperties), ids);
304
- dataLayer.push(trackEvent);
338
+ const trackEvent = Object.assign(Object.assign(Object.assign({ event: payload.event }, pageVariables), trackProperties), ids);
339
+ pushToDataLayer(trackEvent);
305
340
  break;
306
341
  case "identify":
307
342
  const { traits } = payload;
308
- const identifyEvent = Object.assign(Object.assign({ event: "identify" }, traits), ids);
309
- dataLayer.push(identifyEvent);
343
+ const identifyEvent = Object.assign(Object.assign(Object.assign({ event: "identify" }, pageVariables), traits), ids);
344
+ pushToDataLayer(identifyEvent);
310
345
  break;
311
346
  }
312
347
  dataLayer.push(function () {
@@ -1315,7 +1350,7 @@
1315
1350
  if (plugin) {
1316
1351
  for (const event of newEvents) {
1317
1352
  try {
1318
- promises.push(plugin.handle(credentials, event));
1353
+ promises.push(plugin.handle(Object.assign(Object.assign({}, credentials), { debug: true }), event));
1319
1354
  }
1320
1355
  catch (e) {
1321
1356
  console.warn(`[JITSU] Error processing event with internal plugin '${destination.deviceOptions.name}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
@@ -1678,7 +1713,15 @@
1678
1713
  });
1679
1714
  } });
1680
1715
  }
1681
- function jitsuAnalytics(opts) {
1716
+ /**
1717
+ * Fix common mistakes in jitsu configuration
1718
+ * @param opts
1719
+ */
1720
+ function fixOptions(opts) {
1721
+ return Object.assign(Object.assign({}, opts), { host: opts.host.indexOf("https://") !== 0 && opts.host.indexOf("http://") !== 0 ? `https://${opts.host}` : opts.host });
1722
+ }
1723
+ function jitsuAnalytics(_opts) {
1724
+ const opts = fixOptions(_opts);
1682
1725
  const inBrowser = isInBrowser();
1683
1726
  const rt = opts.runtime || (inBrowser ? windowRuntime(opts) : emptyRuntime(opts));
1684
1727
  return createUnderlyingAnalyticsInstance(opts, rt);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jitsu/js",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
4
4
  "description": "",
5
5
  "author": "Jitsu Dev Team <dev@jitsu.com>",
6
6
  "main": "dist/jitsu.cjs.js",
@@ -34,8 +34,8 @@
34
34
  "rollup": "^3.2.5",
35
35
  "ts-jest": "29.0.5",
36
36
  "typescript": "^5.3.3",
37
- "jsondiffpatch": "1.9.0",
38
- "@jitsu/protocols": "1.9.0"
37
+ "@jitsu/protocols": "1.9.1",
38
+ "jsondiffpatch": "1.9.1"
39
39
  },
40
40
  "dependencies": {
41
41
  "analytics": "0.8.9"
@@ -426,7 +426,7 @@ async function processDestinations(
426
426
  if (plugin) {
427
427
  for (const event of newEvents) {
428
428
  try {
429
- promises.push(plugin.handle(credentials, event));
429
+ promises.push(plugin.handle({ ...credentials, debug: true }, event));
430
430
  } catch (e) {
431
431
  console.warn(
432
432
  `[JITSU] Error processing event with internal plugin '${destination.deviceOptions.name}': ${e?.message}`,
@@ -7,51 +7,91 @@ export type GtmDestinationCredentials = {
7
7
  dataLayerName?: string;
8
8
  } & CommonDestinationCredentials;
9
9
 
10
+ function omit(obj: any, ...keys: string[]) {
11
+ return Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));
12
+ }
13
+
10
14
  export const gtmPlugin: InternalPlugin<GtmDestinationCredentials> = {
11
15
  id: "gtm",
12
16
  async handle(config, payload: AnalyticsClientEvent) {
17
+ const debug = !!config.debug;
13
18
  if (!applyFilters(payload, config)) {
14
19
  return;
15
20
  }
16
21
  await initGtmIfNeeded(config, payload);
17
22
 
18
23
  const dataLayer = window[config.dataLayerName || "dataLayer"];
24
+ //traits could be in both nodes, context.traits takes precedence
25
+ const traits = {
26
+ ...(payload?.traits || {}),
27
+ ...(payload?.context?.traits || {}),
28
+ };
29
+ //remove properties that defined separately
30
+ const idsFromTraits = omit(traits, "id", "userId", "user_id", "anonymousId", "userId");
31
+ if (debug) {
32
+ console.debug("GTM plugin will be applied to following payload", payload);
33
+ }
34
+
35
+ // See https://developers.google.com/tag-platform/tag-manager/server-side/common-event-data
36
+ const userData = {
37
+ email_address: traits.email,
38
+ };
19
39
  const ids = {
20
40
  ...(payload.userId ? { user_id: payload.userId, userId: payload.userId } : {}),
21
41
  ...(payload.anonymousId ? { anonymousId: payload.anonymousId } : {}),
42
+ ...idsFromTraits,
43
+ user_data: Object.keys(userData).length > 0 ? userData : undefined,
44
+ };
45
+ if (debug) {
46
+ console.debug("GTM plugin will set following user-related data layer vars", ids);
47
+ }
48
+ const pageProperties = payload.properties || {};
49
+ const pageVariables = {
50
+ page_location: pageProperties.url || payload.context?.page?.url,
51
+ page_title: pageProperties.title || payload.context?.page?.title,
52
+ page_path: pageProperties.path || payload.context?.page?.path,
53
+ page_hash: pageProperties.hash || payload.context?.page?.hash,
54
+ page_search: pageProperties.search || payload.context?.page?.search,
55
+ page_referrer: payload?.context?.page?.referrer ?? "",
56
+ };
57
+ if (debug) {
58
+ console.debug("GTM plugin will set following context (page) related data layer vars", ids);
59
+ }
60
+ const pushToDataLayer = (data: any) => {
61
+ dataLayer.push(data);
62
+ if (debug) {
63
+ console.debug("GTM plugin will push following data to dataLayer", data);
64
+ }
22
65
  };
23
66
  switch (payload.type) {
24
67
  case "page":
25
68
  const { properties: pageProperties, context } = payload;
26
69
  const pageEvent = {
27
70
  event: "page_view",
28
- page_location: pageProperties.url,
29
- page_title: pageProperties.title,
30
- page_path: pageProperties.path,
31
- page_hash: pageProperties.hash,
32
- page_search: pageProperties.search,
33
- page_referrer: context?.page?.referrer ?? "",
71
+ ...pageVariables,
34
72
  ...ids,
35
73
  };
36
- dataLayer.push(pageEvent);
74
+ pushToDataLayer(pageEvent);
37
75
  break;
38
76
  case "track":
39
77
  const { properties: trackProperties } = payload;
40
78
  const trackEvent: any = {
41
79
  event: payload.event,
80
+ ...pageVariables,
42
81
  ...trackProperties,
43
82
  ...ids,
44
83
  };
45
- dataLayer.push(trackEvent);
84
+ pushToDataLayer(trackEvent);
46
85
  break;
47
86
  case "identify":
48
87
  const { traits } = payload;
49
88
  const identifyEvent: any = {
50
89
  event: "identify",
90
+ ...pageVariables,
51
91
  ...traits,
52
92
  ...ids,
53
93
  };
54
- dataLayer.push(identifyEvent);
94
+ pushToDataLayer(identifyEvent);
55
95
  break;
56
96
  }
57
97
  dataLayer.push(function () {
@@ -3,10 +3,11 @@ 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";
6
7
 
7
8
  export type InternalPlugin<T> = {
8
9
  id: string;
9
- handle(config: T, payload: AnalyticsClientEvent): Promise<void>;
10
+ handle(config: T & { debug?: boolean }, payload: AnalyticsClientEvent): Promise<void>;
10
11
  };
11
12
 
12
13
  export type CommonDestinationCredentials = {
package/src/index.ts CHANGED
@@ -16,7 +16,7 @@ export default function parse(input) {
16
16
  if (parseFloat(value) === value) {
17
17
  value = parseFloat(value);
18
18
  }
19
- } catch (e) { }
19
+ } catch (e) {}
20
20
  if (value === null || value === "") {
21
21
  return;
22
22
  }
@@ -24,7 +24,7 @@ export default function parse(input) {
24
24
  }
25
25
 
26
26
  export const emptyAnalytics: AnalyticsInterface = {
27
- setAnonymousId: () => { },
27
+ setAnonymousId: () => {},
28
28
  track: () => Promise.resolve(),
29
29
  page: () => Promise.resolve(),
30
30
  user: () => ({}),
@@ -152,7 +152,20 @@ function createUnderlyingAnalyticsInstance(
152
152
  } as AnalyticsInterface;
153
153
  }
154
154
 
155
- export function jitsuAnalytics(opts: JitsuOptions): AnalyticsInterface {
155
+ /**
156
+ * Fix common mistakes in jitsu configuration
157
+ * @param opts
158
+ */
159
+ function fixOptions(opts: JitsuOptions): JitsuOptions {
160
+ return {
161
+ ...opts,
162
+ host:
163
+ opts.host.indexOf("https://") !== 0 && opts.host.indexOf("http://") !== 0 ? `https://${opts.host}` : opts.host,
164
+ };
165
+ }
166
+
167
+ export function jitsuAnalytics(_opts: JitsuOptions): AnalyticsInterface {
168
+ const opts = fixOptions(_opts);
156
169
  const inBrowser = isInBrowser();
157
170
  const rt = opts.runtime || (inBrowser ? windowRuntime(opts) : emptyRuntime(opts));
158
171
  return createUnderlyingAnalyticsInstance(opts, rt);