@jitsu/js 1.1.0-canary.344.20230430234929 → 1.1.0-canary.391.20230523080206
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/.pnpm-debug.log +23 -0
- package/.turbo/turbo-build.log +95 -65
- package/.turbo/turbo-clean.log +5 -5
- package/__tests__/node/nodejs.test.ts +14 -3
- package/__tests__/playwright/integration.test.ts +1 -2
- package/dist/analytics-plugin.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/jitsu.cjs.js +263 -54
- package/dist/jitsu.es.js +263 -54
- package/dist/web/p.js.txt +262 -54
- package/package.json +2 -2
- package/src/analytics-plugin.ts +33 -13
- package/src/destination-plugins/gtm.ts +112 -0
- package/src/destination-plugins/index.ts +34 -0
- package/src/destination-plugins/logrocket.ts +83 -0
- package/src/{destination-plugins.ts → destination-plugins/tag.ts} +3 -28
- package/src/index.ts +13 -3
- package/dist/destination-plugins.d.ts +0 -13
package/dist/web/p.js.txt
CHANGED
|
@@ -68,7 +68,50 @@
|
|
|
68
68
|
return ke(_objectSpread2(_objectSpread2({}, defaultSettings), opts));
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
function findScript(src) {
|
|
72
|
+
const scripts = Array.prototype.slice.call(window.document.querySelectorAll("script"));
|
|
73
|
+
return scripts.find(s => s.src === src);
|
|
74
|
+
}
|
|
75
|
+
function loadScript(src, attributes) {
|
|
76
|
+
const found = findScript(src);
|
|
77
|
+
if (found !== undefined) {
|
|
78
|
+
const status = found === null || found === void 0 ? void 0 : found.getAttribute("status");
|
|
79
|
+
if (status === "loaded") {
|
|
80
|
+
return Promise.resolve(found);
|
|
81
|
+
}
|
|
82
|
+
if (status === "loading") {
|
|
83
|
+
return new Promise((resolve, reject) => {
|
|
84
|
+
found.addEventListener("load", () => resolve(found));
|
|
85
|
+
found.addEventListener("error", err => reject(err));
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
var _a;
|
|
91
|
+
const script = window.document.createElement("script");
|
|
92
|
+
script.type = "text/javascript";
|
|
93
|
+
script.src = src;
|
|
94
|
+
script.async = true;
|
|
95
|
+
script.setAttribute("status", "loading");
|
|
96
|
+
for (const [k, v] of Object.entries(attributes !== null && attributes !== void 0 ? attributes : {})) {
|
|
97
|
+
script.setAttribute(k, v);
|
|
98
|
+
}
|
|
99
|
+
script.onload = () => {
|
|
100
|
+
script.onerror = script.onload = null;
|
|
101
|
+
script.setAttribute("status", "loaded");
|
|
102
|
+
resolve(script);
|
|
103
|
+
};
|
|
104
|
+
script.onerror = () => {
|
|
105
|
+
script.onerror = script.onload = null;
|
|
106
|
+
script.setAttribute("status", "error");
|
|
107
|
+
reject(new Error(`Failed to load ${src}`));
|
|
108
|
+
};
|
|
109
|
+
const tag = window.document.getElementsByTagName("script")[0];
|
|
110
|
+
(_a = tag.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(script, tag);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
var __awaiter$3 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
72
115
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
73
116
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
74
117
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
@@ -77,18 +120,10 @@
|
|
|
77
120
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
78
121
|
});
|
|
79
122
|
};
|
|
80
|
-
function satisfyFilter(filter, subject) {
|
|
81
|
-
return filter === "*" || filter.toLowerCase().trim() === (subject || "").trim().toLowerCase();
|
|
82
|
-
}
|
|
83
|
-
function applyFilters(event, creds) {
|
|
84
|
-
const { hosts = ["*"], events = ["*"] } = creds;
|
|
85
|
-
return (!!hosts.find(hostFilter => { var _a; return satisfyFilter(hostFilter, (_a = event.context) === null || _a === void 0 ? void 0 : _a.host); }) &&
|
|
86
|
-
!!events.find(eventFilter => satisfyFilter(eventFilter, event.type)));
|
|
87
|
-
}
|
|
88
123
|
const tagPlugin = {
|
|
89
124
|
id: "tag",
|
|
90
125
|
handle(config, payload) {
|
|
91
|
-
return __awaiter$
|
|
126
|
+
return __awaiter$3(this, void 0, void 0, function* () {
|
|
92
127
|
if (!applyFilters(payload, config)) {
|
|
93
128
|
return;
|
|
94
129
|
}
|
|
@@ -156,53 +191,206 @@
|
|
|
156
191
|
function replaceMacro(code, event) {
|
|
157
192
|
return code.replace(/{{\s*event\s*}}/g, JSON.stringify(event));
|
|
158
193
|
}
|
|
159
|
-
const internalDestinationPlugins = {
|
|
160
|
-
[tagPlugin.id]: tagPlugin,
|
|
161
|
-
};
|
|
162
194
|
|
|
163
|
-
function
|
|
164
|
-
|
|
165
|
-
return
|
|
195
|
+
var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
196
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
197
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
198
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
199
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
200
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
201
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
const logrocketPlugin = {
|
|
205
|
+
id: "logrocket",
|
|
206
|
+
handle(config, payload) {
|
|
207
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
208
|
+
if (!applyFilters(payload, config)) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
initLogrocketIfNeeded(config.appId);
|
|
212
|
+
const action = logRocket => {
|
|
213
|
+
if (payload.type === "identify" && payload.userId) {
|
|
214
|
+
logRocket.identify(payload.userId, payload.traits || {});
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
getLogRocketQueue().push(action);
|
|
218
|
+
if (getLogRocketState() === "loaded") {
|
|
219
|
+
flushLogRocketQueue(window["LogRocket"]);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
function getLogRocketState() {
|
|
225
|
+
return window["__jitsuLrState"] || "fresh";
|
|
166
226
|
}
|
|
167
|
-
function
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
227
|
+
function setLogRocketState(s) {
|
|
228
|
+
window["__jitsuLrState"] = s;
|
|
229
|
+
}
|
|
230
|
+
function getLogRocketQueue() {
|
|
231
|
+
return window["__jitsuLrQueue"] || (window["__jitsuLrQueue"] = []);
|
|
232
|
+
}
|
|
233
|
+
function flushLogRocketQueue(lr) {
|
|
234
|
+
const queue = getLogRocketQueue();
|
|
235
|
+
while (queue.length > 0) {
|
|
236
|
+
const method = queue.shift();
|
|
237
|
+
try {
|
|
238
|
+
const res = method(lr);
|
|
239
|
+
if (res) {
|
|
240
|
+
res.catch(e => console.warn(`Async LogRocket method failed: ${e.message}`, e));
|
|
241
|
+
}
|
|
173
242
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
found.addEventListener("load", () => resolve(found));
|
|
177
|
-
found.addEventListener("error", err => reject(err));
|
|
178
|
-
});
|
|
243
|
+
catch (e) {
|
|
244
|
+
console.warn(`LogRocket method failed: ${e.message}`, e);
|
|
179
245
|
}
|
|
180
246
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
script.async = true;
|
|
187
|
-
script.setAttribute("status", "loading");
|
|
188
|
-
for (const [k, v] of Object.entries(attributes !== null && attributes !== void 0 ? attributes : {})) {
|
|
189
|
-
script.setAttribute(k, v);
|
|
247
|
+
}
|
|
248
|
+
function initLogrocketIfNeeded(appId) {
|
|
249
|
+
return __awaiter$2(this, void 0, void 0, function* () {
|
|
250
|
+
if (getLogRocketState() !== "fresh") {
|
|
251
|
+
return;
|
|
190
252
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
253
|
+
setLogRocketState("loading");
|
|
254
|
+
loadScript(`https://cdn.lr-ingest.io/LogRocket.min.js`, { crossOrigin: "anonymous" })
|
|
255
|
+
.then(() => {
|
|
256
|
+
if (window["LogRocket"]) {
|
|
257
|
+
try {
|
|
258
|
+
window["LogRocket"].init(appId);
|
|
259
|
+
}
|
|
260
|
+
catch (e) {
|
|
261
|
+
console.warn(`LogRocket (id=${appId}) init failed: ${e.message}`, e);
|
|
262
|
+
setLogRocketState("failed");
|
|
263
|
+
}
|
|
264
|
+
setLogRocketState("loaded");
|
|
265
|
+
flushLogRocketQueue(window["LogRocket"]);
|
|
266
|
+
}
|
|
267
|
+
})
|
|
268
|
+
.catch(e => {
|
|
269
|
+
console.warn(`LogRocket (id=${appId}) init failed: ${e.message}`, e);
|
|
270
|
+
setLogRocketState("failed");
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
276
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
277
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
278
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
279
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
280
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
281
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
282
|
+
});
|
|
283
|
+
};
|
|
284
|
+
const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
|
|
285
|
+
const gtmPlugin = {
|
|
286
|
+
id: "gtm",
|
|
287
|
+
handle(config, payload) {
|
|
288
|
+
var _a, _b;
|
|
289
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
290
|
+
if (!applyFilters(payload, config)) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
yield initGtmIfNeeded(config);
|
|
294
|
+
const dataLayer = window[config.dataLayerName || "dataLayer"];
|
|
295
|
+
switch (payload.type) {
|
|
296
|
+
case "page":
|
|
297
|
+
const { properties: pageProperties, context } = payload;
|
|
298
|
+
const pageEvent = {
|
|
299
|
+
event: "page_view",
|
|
300
|
+
url: pageProperties.url,
|
|
301
|
+
title: pageProperties.title,
|
|
302
|
+
referer: (_b = (_a = context === null || context === void 0 ? void 0 : context.page) === null || _a === void 0 ? void 0 : _a.referrer) !== null && _b !== void 0 ? _b : "",
|
|
303
|
+
};
|
|
304
|
+
if (config.debug) {
|
|
305
|
+
console.log("gtag push", pageEvent);
|
|
306
|
+
}
|
|
307
|
+
dataLayer.push(pageEvent);
|
|
308
|
+
break;
|
|
309
|
+
case "track":
|
|
310
|
+
const { properties: trackProperties } = payload;
|
|
311
|
+
const trackEvent = Object.assign({ event: payload.event }, trackProperties);
|
|
312
|
+
if (payload.userId) {
|
|
313
|
+
trackEvent.userId = payload.userId;
|
|
314
|
+
}
|
|
315
|
+
if (payload.anonymousId) {
|
|
316
|
+
trackEvent.anonymousId = payload.anonymousId;
|
|
317
|
+
}
|
|
318
|
+
if (config.debug) {
|
|
319
|
+
console.log("gtag push", trackEvent);
|
|
320
|
+
}
|
|
321
|
+
dataLayer.push(trackEvent);
|
|
322
|
+
break;
|
|
323
|
+
case "identify":
|
|
324
|
+
const { traits } = payload;
|
|
325
|
+
const identifyEvent = Object.assign({ event: "identify" }, traits);
|
|
326
|
+
if (payload.userId) {
|
|
327
|
+
identifyEvent.userId = payload.userId;
|
|
328
|
+
}
|
|
329
|
+
if (payload.anonymousId) {
|
|
330
|
+
identifyEvent.anonymousId = payload.anonymousId;
|
|
331
|
+
}
|
|
332
|
+
if (config.debug) {
|
|
333
|
+
console.log("gtag push", identifyEvent);
|
|
334
|
+
}
|
|
335
|
+
dataLayer.push(identifyEvent);
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
function getGtmState() {
|
|
342
|
+
return window["__jitsuGtmState"] || "fresh";
|
|
343
|
+
}
|
|
344
|
+
function setGtmState(s) {
|
|
345
|
+
window["__jitsuGtmState"] = s;
|
|
346
|
+
}
|
|
347
|
+
function initGtmIfNeeded(config) {
|
|
348
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
349
|
+
if (getGtmState() !== "fresh") {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
setGtmState("loading");
|
|
353
|
+
const dlName = config.dataLayerName || "dataLayer";
|
|
354
|
+
const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
|
|
355
|
+
const previewParams = config.preview
|
|
356
|
+
? `>m_preview=${config.preview}>m_auth=${config.auth}>m_cookies_win=x`
|
|
357
|
+
: "";
|
|
358
|
+
const scriptSrc = `${config.customScriptSrc || defaultScriptSrc}?id=${config.containerId}${dlParam}${previewParams}`;
|
|
359
|
+
window[dlName] = window[dlName] || [];
|
|
360
|
+
const gtag = function () {
|
|
361
|
+
window[dlName].push(arguments);
|
|
200
362
|
};
|
|
201
|
-
|
|
202
|
-
(
|
|
363
|
+
// @ts-ignore
|
|
364
|
+
gtag("js", new Date());
|
|
365
|
+
// @ts-ignore
|
|
366
|
+
gtag("config", config.containerId);
|
|
367
|
+
loadScript(scriptSrc)
|
|
368
|
+
.then(() => {
|
|
369
|
+
setGtmState("loaded");
|
|
370
|
+
})
|
|
371
|
+
.catch(e => {
|
|
372
|
+
console.warn(`GTM (containerId=${config.containerId}) init failed: ${e.message}`, e);
|
|
373
|
+
setGtmState("failed");
|
|
374
|
+
});
|
|
203
375
|
});
|
|
204
376
|
}
|
|
205
377
|
|
|
378
|
+
function satisfyFilter(filter, subject) {
|
|
379
|
+
return filter === "*" || filter.toLowerCase().trim() === (subject || "").trim().toLowerCase();
|
|
380
|
+
}
|
|
381
|
+
function applyFilters(event, creds) {
|
|
382
|
+
const { hosts = "*", events = "*" } = creds;
|
|
383
|
+
const eventsArray = events.split("\n");
|
|
384
|
+
return (!!hosts.split("\n").find(hostFilter => { var _a; return satisfyFilter(hostFilter, (_a = event.context) === null || _a === void 0 ? void 0 : _a.host); }) &&
|
|
385
|
+
(!!eventsArray.find(eventFilter => satisfyFilter(eventFilter, event.type)) ||
|
|
386
|
+
!!eventsArray.find(eventFilter => satisfyFilter(eventFilter, event.event))));
|
|
387
|
+
}
|
|
388
|
+
const internalDestinationPlugins = {
|
|
389
|
+
[tagPlugin.id]: tagPlugin,
|
|
390
|
+
[gtmPlugin.id]: gtmPlugin,
|
|
391
|
+
[logrocketPlugin.id]: logrocketPlugin,
|
|
392
|
+
};
|
|
393
|
+
|
|
206
394
|
/* global analytics */
|
|
207
395
|
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
208
396
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -221,6 +409,8 @@
|
|
|
221
409
|
debug: false,
|
|
222
410
|
fetch: null,
|
|
223
411
|
echoEvents: false,
|
|
412
|
+
cookieDomain: undefined,
|
|
413
|
+
runtime: undefined,
|
|
224
414
|
};
|
|
225
415
|
const parseQuery = (qs) => {
|
|
226
416
|
if (!qs) {
|
|
@@ -444,7 +634,7 @@
|
|
|
444
634
|
userAgent: runtime.userAgent(),
|
|
445
635
|
locale: runtime.language(),
|
|
446
636
|
screen: runtime.screen(),
|
|
447
|
-
traits: payload.type != "identify" ? Object.assign({}, (restoreTraits(storage) || {})) : undefined,
|
|
637
|
+
traits: payload.type != "identify" && payload.type != "group" ? Object.assign({}, (restoreTraits(storage) || {})) : undefined,
|
|
448
638
|
page: {
|
|
449
639
|
path: properties.path || (parsedUrl && parsedUrl.pathname),
|
|
450
640
|
referrer: referrer,
|
|
@@ -453,7 +643,7 @@
|
|
|
453
643
|
search: properties.search || (parsedUrl && parsedUrl.search),
|
|
454
644
|
title: properties.title || runtime.pageTitle(),
|
|
455
645
|
url: properties.url || url,
|
|
456
|
-
|
|
646
|
+
encoding: properties.encoding || runtime.documentEncoding(),
|
|
457
647
|
},
|
|
458
648
|
campaign: parseUtms(query),
|
|
459
649
|
};
|
|
@@ -466,12 +656,12 @@
|
|
|
466
656
|
return __awaiter(this, void 0, void 0, function* () {
|
|
467
657
|
const promises = [];
|
|
468
658
|
for (const destination of destinations) {
|
|
659
|
+
const credentials = Object.assign(Object.assign({}, destination.credentials), destination.options);
|
|
469
660
|
if (destination.deviceOptions.type === "internal-plugin") {
|
|
470
661
|
const plugin = internalDestinationPlugins[destination.deviceOptions.name];
|
|
471
662
|
if (plugin) {
|
|
472
663
|
try {
|
|
473
664
|
//to support old versions, where credentials were stored in root
|
|
474
|
-
const credentials = destination.credentials || destination;
|
|
475
665
|
promises.push(plugin.handle(credentials, event));
|
|
476
666
|
}
|
|
477
667
|
catch (e) {
|
|
@@ -491,7 +681,7 @@
|
|
|
491
681
|
else {
|
|
492
682
|
let pluginInstance;
|
|
493
683
|
try {
|
|
494
|
-
pluginInstance = (typeof plugin === "function" ? plugin : plugin.init)(
|
|
684
|
+
pluginInstance = (typeof plugin === "function" ? plugin : plugin.init)(credentials);
|
|
495
685
|
}
|
|
496
686
|
catch (e) {
|
|
497
687
|
console.warn(`[JITSU] Error creating plugin '${destination.deviceOptions.moduleVarName}@${destination.deviceOptions.packageCdn}' for destination '${destination.id}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
|
|
@@ -561,7 +751,7 @@
|
|
|
561
751
|
}
|
|
562
752
|
if (response.destinations) {
|
|
563
753
|
if (jitsuConfig.debug) {
|
|
564
|
-
console.log(`[JITSU] Processing device
|
|
754
|
+
console.log(`[JITSU] Processing device destinations: `, JSON.stringify(response.destinations, null, 2));
|
|
565
755
|
}
|
|
566
756
|
return processDestinations(response.destinations, method, adjustedPayload, !!jitsuConfig.debug, instance);
|
|
567
757
|
}
|
|
@@ -590,9 +780,10 @@
|
|
|
590
780
|
persistentStorage.removeItem(key);
|
|
591
781
|
},
|
|
592
782
|
});
|
|
783
|
+
const instanceConfig = Object.assign(Object.assign({}, config), pluginConfig);
|
|
593
784
|
return {
|
|
594
785
|
name: "jitsu",
|
|
595
|
-
config:
|
|
786
|
+
config: instanceConfig,
|
|
596
787
|
initialize: args => {
|
|
597
788
|
const { config } = args;
|
|
598
789
|
if (config.debug) {
|
|
@@ -620,6 +811,16 @@
|
|
|
620
811
|
//clear storage cache
|
|
621
812
|
Object.keys(storageCache).forEach(key => delete storageCache[key]);
|
|
622
813
|
},
|
|
814
|
+
methods: {
|
|
815
|
+
//analytics doesn't support group as a base method, so we need to add it manually
|
|
816
|
+
group(groupId, traits, options, callback) {
|
|
817
|
+
const analyticsInstance = this.instance;
|
|
818
|
+
const user = analyticsInstance.user();
|
|
819
|
+
const userId = (options === null || options === void 0 ? void 0 : options.userId) || (user === null || user === void 0 ? void 0 : user.userId);
|
|
820
|
+
const anonymousId = (options === null || options === void 0 ? void 0 : options.anonymousId) || (user === null || user === void 0 ? void 0 : user.anonymousId);
|
|
821
|
+
return send("group", Object.assign(Object.assign({ type: "group", groupId, traits }, (anonymousId ? { anonymousId } : {})), (userId ? { userId } : {})), instanceConfig, analyticsInstance, cachingStorageWrapper(analyticsInstance.storage));
|
|
822
|
+
},
|
|
823
|
+
},
|
|
623
824
|
};
|
|
624
825
|
};
|
|
625
826
|
function getSeed() {
|
|
@@ -683,7 +884,14 @@
|
|
|
683
884
|
return originalPage(...args);
|
|
684
885
|
}
|
|
685
886
|
};
|
|
686
|
-
return analytics
|
|
887
|
+
return Object.assign(Object.assign({}, analytics), { group(groupId, traits, options, callback) {
|
|
888
|
+
for (const plugin of Object.values(analytics.plugins)) {
|
|
889
|
+
if (plugin["group"]) {
|
|
890
|
+
plugin["group"](groupId, traits, options, callback);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
return Promise.resolve({});
|
|
894
|
+
} });
|
|
687
895
|
}
|
|
688
896
|
function jitsuAnalytics(opts) {
|
|
689
897
|
const inBrowser = isInBrowser();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jitsu/js",
|
|
3
|
-
"version": "1.1.0-canary.
|
|
3
|
+
"version": "1.1.0-canary.391.20230523080206",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Jitsu Dev Team <dev@jitsu.com>",
|
|
6
6
|
"main": "dist/jitsu.cjs.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"rollup": "^3.2.5",
|
|
35
35
|
"ts-jest": "29.0.5",
|
|
36
36
|
"typescript": "^4.9.5",
|
|
37
|
-
"@jitsu/protocols": "1.1.0-canary.
|
|
37
|
+
"@jitsu/protocols": "1.1.0-canary.391.20230523080206"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"analytics": "^0.8.1"
|
package/src/analytics-plugin.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/* global analytics */
|
|
2
2
|
|
|
3
3
|
import { JitsuOptions, PersistentStorage, RuntimeFacade } from "./jitsu";
|
|
4
|
-
import { AnalyticsClientEvent } from "@jitsu/protocols/analytics";
|
|
4
|
+
import { AnalyticsClientEvent, Callback, ID, JSONObject, Options } from "@jitsu/protocols/analytics";
|
|
5
5
|
import parse from "./index";
|
|
6
6
|
import { AnalyticsInstance, AnalyticsPlugin } from "analytics";
|
|
7
|
-
import { internalDestinationPlugins } from "./destination-plugins";
|
|
8
7
|
import { loadScript } from "./script-loader";
|
|
8
|
+
import { internalDestinationPlugins } from "./destination-plugins";
|
|
9
9
|
|
|
10
|
-
const config: JitsuOptions = {
|
|
10
|
+
const config: Required<JitsuOptions> = {
|
|
11
11
|
/* Your segment writeKey */
|
|
12
12
|
writeKey: null,
|
|
13
13
|
/* Disable anonymous MTU */
|
|
@@ -15,6 +15,8 @@ const config: JitsuOptions = {
|
|
|
15
15
|
debug: false,
|
|
16
16
|
fetch: null,
|
|
17
17
|
echoEvents: false,
|
|
18
|
+
cookieDomain: undefined,
|
|
19
|
+
runtime: undefined,
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
export const parseQuery = (qs?: string): Record<string, string> => {
|
|
@@ -261,7 +263,7 @@ function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentSt
|
|
|
261
263
|
userAgent: runtime.userAgent(),
|
|
262
264
|
locale: runtime.language(),
|
|
263
265
|
screen: runtime.screen(),
|
|
264
|
-
traits: payload.type != "identify" ? { ...(restoreTraits(storage) || {}) } : undefined,
|
|
266
|
+
traits: payload.type != "identify" && payload.type != "group" ? { ...(restoreTraits(storage) || {}) } : undefined,
|
|
265
267
|
page: {
|
|
266
268
|
path: properties.path || (parsedUrl && parsedUrl.pathname),
|
|
267
269
|
referrer: referrer,
|
|
@@ -270,7 +272,7 @@ function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentSt
|
|
|
270
272
|
search: properties.search || (parsedUrl && parsedUrl.search),
|
|
271
273
|
title: properties.title || runtime.pageTitle(),
|
|
272
274
|
url: properties.url || url,
|
|
273
|
-
|
|
275
|
+
encoding: properties.encoding || runtime.documentEncoding(),
|
|
274
276
|
},
|
|
275
277
|
campaign: parseUtms(query),
|
|
276
278
|
};
|
|
@@ -291,6 +293,7 @@ export type DestinationDescriptor = {
|
|
|
291
293
|
id: string;
|
|
292
294
|
destinationType: string;
|
|
293
295
|
credentials: any;
|
|
296
|
+
options: any;
|
|
294
297
|
deviceOptions: DeviceOptions;
|
|
295
298
|
};
|
|
296
299
|
export type AnalyticsPluginDescriptor = {
|
|
@@ -315,12 +318,12 @@ async function processDestinations(
|
|
|
315
318
|
) {
|
|
316
319
|
const promises: Promise<any>[] = [];
|
|
317
320
|
for (const destination of destinations) {
|
|
321
|
+
const credentials = { ...destination.credentials, ...destination.options };
|
|
322
|
+
|
|
318
323
|
if (destination.deviceOptions.type === "internal-plugin") {
|
|
319
324
|
const plugin = internalDestinationPlugins[destination.deviceOptions.name];
|
|
320
325
|
if (plugin) {
|
|
321
326
|
try {
|
|
322
|
-
//to support old versions, where credentials were stored in root
|
|
323
|
-
const credentials = destination.credentials || destination;
|
|
324
327
|
promises.push(plugin.handle(credentials, event));
|
|
325
328
|
} catch (e) {
|
|
326
329
|
console.warn(
|
|
@@ -343,7 +346,7 @@ async function processDestinations(
|
|
|
343
346
|
} else {
|
|
344
347
|
let pluginInstance: any;
|
|
345
348
|
try {
|
|
346
|
-
pluginInstance = (typeof plugin === "function" ? plugin : plugin.init)(
|
|
349
|
+
pluginInstance = (typeof plugin === "function" ? plugin : plugin.init)(credentials);
|
|
347
350
|
} catch (e) {
|
|
348
351
|
console.warn(
|
|
349
352
|
`[JITSU] Error creating plugin '${destination.deviceOptions.moduleVarName}@${destination.deviceOptions.packageCdn}' for destination '${destination.id}': ${e?.message}`,
|
|
@@ -441,7 +444,7 @@ function send(
|
|
|
441
444
|
}
|
|
442
445
|
if (response.destinations) {
|
|
443
446
|
if (jitsuConfig.debug) {
|
|
444
|
-
console.log(`[JITSU] Processing device
|
|
447
|
+
console.log(`[JITSU] Processing device destinations: `, JSON.stringify(response.destinations, null, 2));
|
|
445
448
|
}
|
|
446
449
|
return processDestinations(response.destinations, method, adjustedPayload, !!jitsuConfig.debug, instance);
|
|
447
450
|
}
|
|
@@ -471,12 +474,13 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
|
|
|
471
474
|
persistentStorage.removeItem(key);
|
|
472
475
|
},
|
|
473
476
|
});
|
|
477
|
+
const instanceConfig = {
|
|
478
|
+
...config,
|
|
479
|
+
...pluginConfig,
|
|
480
|
+
};
|
|
474
481
|
return {
|
|
475
482
|
name: "jitsu",
|
|
476
|
-
config:
|
|
477
|
-
...config,
|
|
478
|
-
...pluginConfig,
|
|
479
|
-
},
|
|
483
|
+
config: instanceConfig,
|
|
480
484
|
initialize: args => {
|
|
481
485
|
const { config } = args;
|
|
482
486
|
if (config.debug) {
|
|
@@ -504,6 +508,22 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
|
|
|
504
508
|
//clear storage cache
|
|
505
509
|
Object.keys(storageCache).forEach(key => delete storageCache[key]);
|
|
506
510
|
},
|
|
511
|
+
methods: {
|
|
512
|
+
//analytics doesn't support group as a base method, so we need to add it manually
|
|
513
|
+
group(groupId?: ID, traits?: JSONObject | null, options?: Options, callback?: Callback) {
|
|
514
|
+
const analyticsInstance = this.instance;
|
|
515
|
+
const user = analyticsInstance.user();
|
|
516
|
+
const userId = options?.userId || user?.userId;
|
|
517
|
+
const anonymousId = options?.anonymousId || user?.anonymousId;
|
|
518
|
+
return send(
|
|
519
|
+
"group",
|
|
520
|
+
{ type: "group", groupId, traits, ...(anonymousId ? { anonymousId } : {}), ...(userId ? { userId } : {}) },
|
|
521
|
+
instanceConfig,
|
|
522
|
+
analyticsInstance,
|
|
523
|
+
cachingStorageWrapper(analyticsInstance.storage)
|
|
524
|
+
);
|
|
525
|
+
},
|
|
526
|
+
},
|
|
507
527
|
};
|
|
508
528
|
};
|
|
509
529
|
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { loadScript } from "../script-loader";
|
|
2
|
+
import { AnalyticsClientEvent } from "@jitsu/protocols/analytics";
|
|
3
|
+
import { applyFilters, CommonDestinationCredentials, InternalPlugin } from "./index";
|
|
4
|
+
|
|
5
|
+
const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
|
|
6
|
+
|
|
7
|
+
export type GtmDestinationCredentials = {
|
|
8
|
+
debug: boolean;
|
|
9
|
+
containerId: string;
|
|
10
|
+
dataLayerName: string;
|
|
11
|
+
preview: string;
|
|
12
|
+
auth: string;
|
|
13
|
+
customScriptSrc: string;
|
|
14
|
+
} & CommonDestinationCredentials;
|
|
15
|
+
|
|
16
|
+
export const gtmPlugin: InternalPlugin<GtmDestinationCredentials> = {
|
|
17
|
+
id: "gtm",
|
|
18
|
+
async handle(config, payload: AnalyticsClientEvent) {
|
|
19
|
+
if (!applyFilters(payload, config)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
await initGtmIfNeeded(config);
|
|
23
|
+
|
|
24
|
+
const dataLayer = window[config.dataLayerName || "dataLayer"];
|
|
25
|
+
|
|
26
|
+
switch (payload.type) {
|
|
27
|
+
case "page":
|
|
28
|
+
const { properties: pageProperties, context } = payload;
|
|
29
|
+
const pageEvent = {
|
|
30
|
+
event: "page_view",
|
|
31
|
+
url: pageProperties.url,
|
|
32
|
+
title: pageProperties.title,
|
|
33
|
+
referer: context?.page?.referrer ?? "",
|
|
34
|
+
};
|
|
35
|
+
if (config.debug) {
|
|
36
|
+
console.log("gtag push", pageEvent);
|
|
37
|
+
}
|
|
38
|
+
dataLayer.push(pageEvent);
|
|
39
|
+
break;
|
|
40
|
+
case "track":
|
|
41
|
+
const { properties: trackProperties } = payload;
|
|
42
|
+
const trackEvent: any = { event: payload.event, ...trackProperties };
|
|
43
|
+
if (payload.userId) {
|
|
44
|
+
trackEvent.userId = payload.userId;
|
|
45
|
+
}
|
|
46
|
+
if (payload.anonymousId) {
|
|
47
|
+
trackEvent.anonymousId = payload.anonymousId;
|
|
48
|
+
}
|
|
49
|
+
if (config.debug) {
|
|
50
|
+
console.log("gtag push", trackEvent);
|
|
51
|
+
}
|
|
52
|
+
dataLayer.push(trackEvent);
|
|
53
|
+
break;
|
|
54
|
+
case "identify":
|
|
55
|
+
const { traits } = payload;
|
|
56
|
+
const identifyEvent: any = { event: "identify", ...traits };
|
|
57
|
+
if (payload.userId) {
|
|
58
|
+
identifyEvent.userId = payload.userId;
|
|
59
|
+
}
|
|
60
|
+
if (payload.anonymousId) {
|
|
61
|
+
identifyEvent.anonymousId = payload.anonymousId;
|
|
62
|
+
}
|
|
63
|
+
if (config.debug) {
|
|
64
|
+
console.log("gtag push", identifyEvent);
|
|
65
|
+
}
|
|
66
|
+
dataLayer.push(identifyEvent);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type GtmState = "fresh" | "loading" | "loaded" | "failed";
|
|
73
|
+
|
|
74
|
+
function getGtmState(): GtmState {
|
|
75
|
+
return window["__jitsuGtmState"] || "fresh";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function setGtmState(s: GtmState) {
|
|
79
|
+
window["__jitsuGtmState"] = s;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function initGtmIfNeeded(config: GtmDestinationCredentials) {
|
|
83
|
+
if (getGtmState() !== "fresh") {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
setGtmState("loading");
|
|
87
|
+
|
|
88
|
+
const dlName = config.dataLayerName || "dataLayer";
|
|
89
|
+
const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
|
|
90
|
+
const previewParams = config.preview
|
|
91
|
+
? `>m_preview=${config.preview}>m_auth=${config.auth}>m_cookies_win=x`
|
|
92
|
+
: "";
|
|
93
|
+
const scriptSrc = `${config.customScriptSrc || defaultScriptSrc}?id=${config.containerId}${dlParam}${previewParams}`;
|
|
94
|
+
|
|
95
|
+
window[dlName] = window[dlName] || [];
|
|
96
|
+
const gtag = function () {
|
|
97
|
+
window[dlName].push(arguments);
|
|
98
|
+
};
|
|
99
|
+
// @ts-ignore
|
|
100
|
+
gtag("js", new Date());
|
|
101
|
+
// @ts-ignore
|
|
102
|
+
gtag("config", config.containerId);
|
|
103
|
+
|
|
104
|
+
loadScript(scriptSrc)
|
|
105
|
+
.then(() => {
|
|
106
|
+
setGtmState("loaded");
|
|
107
|
+
})
|
|
108
|
+
.catch(e => {
|
|
109
|
+
console.warn(`GTM (containerId=${config.containerId}) init failed: ${e.message}`, e);
|
|
110
|
+
setGtmState("failed");
|
|
111
|
+
});
|
|
112
|
+
}
|