@jitsu/js 0.0.1-alpha.127 → 0.0.1-alpha.174
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 +33 -15
- package/.turbo/turbo-clean.log +5 -5
- package/__tests__/simple-syrup.ts +9 -3
- package/dist/jitsu.cjs.js +88 -8
- package/dist/jitsu.d.ts +23 -0
- package/dist/jitsu.es.js +88 -8
- package/dist/web/p.js.txt +88 -8
- package/package.json +2 -2
- package/src/analytics-plugin.ts +91 -8
- package/src/jitsu.ts +23 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,15 +1,33 @@
|
|
|
1
|
-
@jitsu/js:build: cache hit, replaying output [
|
|
2
|
-
[
|
|
3
|
-
[
|
|
4
|
-
[
|
|
5
|
-
[
|
|
6
|
-
[
|
|
7
|
-
[
|
|
8
|
-
[
|
|
9
|
-
[
|
|
10
|
-
[
|
|
11
|
-
[
|
|
12
|
-
[
|
|
13
|
-
[
|
|
14
|
-
[
|
|
15
|
-
[
|
|
1
|
+
@jitsu/js:build: cache hit, replaying output [2mfd2896b82ec69198[0m
|
|
2
|
+
[36m@jitsu/js:build: [0m
|
|
3
|
+
[36m@jitsu/js:build: [0m> @jitsu/js@0.0.0 build /Users/ildarnurislamov/Projects/onetag/libs/jitsu-js
|
|
4
|
+
[36m@jitsu/js:build: [0m> tsc -p . && rollup -c && cp compiled/src/*.d.ts dist
|
|
5
|
+
[36m@jitsu/js:build: [0m
|
|
6
|
+
[36m@jitsu/js:build: [0m[36m
|
|
7
|
+
[36m@jitsu/js:build: [0m[1m./compiled/src/browser.js[22m → [1mdist/web/p.js.txt[22m...[39m
|
|
8
|
+
[36m@jitsu/js:build: [0m[1m[33m(!) Circular dependency[39m[22m
|
|
9
|
+
[36m@jitsu/js:build: [0mcompiled/src/index.js -> compiled/src/analytics-plugin.js -> compiled/src/index.js
|
|
10
|
+
[36m@jitsu/js:build: [0m[1m[33m(!) Use of eval is strongly discouraged[39m[22m
|
|
11
|
+
[36m@jitsu/js:build: [0m[90mhttps://rollupjs.org/guide/en/#avoiding-eval[39m
|
|
12
|
+
[36m@jitsu/js:build: [0m[1mcompiled/src/analytics-plugin.js[22m
|
|
13
|
+
[36m@jitsu/js:build: [0m[90m258: })()`;
|
|
14
|
+
[36m@jitsu/js:build: [0m259: try {
|
|
15
|
+
[36m@jitsu/js:build: [0m260: eval(iif);
|
|
16
|
+
[36m@jitsu/js:build: [0m ^
|
|
17
|
+
[36m@jitsu/js:build: [0m261: }
|
|
18
|
+
[36m@jitsu/js:build: [0m262: catch (e) {[39m
|
|
19
|
+
[36m@jitsu/js:build: [0m[32mcreated [1mdist/web/p.js.txt[22m in [1m184ms[22m[39m
|
|
20
|
+
[36m@jitsu/js:build: [0m[36m
|
|
21
|
+
[36m@jitsu/js:build: [0m[1m./compiled/src/index.js, ./compiled/src/jitsu.js, ./compiled/src/analytics-plugin.js[22m → [1mdist/jitsu.es.js, dist/jitsu.cjs.js[22m...[39m
|
|
22
|
+
[36m@jitsu/js:build: [0m[1m[33m(!) Circular dependency[39m[22m
|
|
23
|
+
[36m@jitsu/js:build: [0mcompiled/src/index.js -> compiled/src/analytics-plugin.js -> compiled/src/index.js
|
|
24
|
+
[36m@jitsu/js:build: [0m[1m[33m(!) Use of eval is strongly discouraged[39m[22m
|
|
25
|
+
[36m@jitsu/js:build: [0m[90mhttps://rollupjs.org/guide/en/#avoiding-eval[39m
|
|
26
|
+
[36m@jitsu/js:build: [0m[1mcompiled/src/analytics-plugin.js[22m
|
|
27
|
+
[36m@jitsu/js:build: [0m[90m258: })()`;
|
|
28
|
+
[36m@jitsu/js:build: [0m259: try {
|
|
29
|
+
[36m@jitsu/js:build: [0m260: eval(iif);
|
|
30
|
+
[36m@jitsu/js:build: [0m ^
|
|
31
|
+
[36m@jitsu/js:build: [0m261: }
|
|
32
|
+
[36m@jitsu/js:build: [0m262: catch (e) {[39m
|
|
33
|
+
[36m@jitsu/js:build: [0m[32mcreated [1mdist/jitsu.es.js, dist/jitsu.cjs.js[22m in [1m126ms[22m[39m
|
package/.turbo/turbo-clean.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
@jitsu/js:clean: cache hit, replaying output [
|
|
2
|
-
[
|
|
3
|
-
[
|
|
4
|
-
[
|
|
5
|
-
[
|
|
1
|
+
@jitsu/js:clean: cache hit, replaying output [2mcc849d2fe2e435e1[0m
|
|
2
|
+
[36m@jitsu/js:clean: [0m
|
|
3
|
+
[36m@jitsu/js:clean: [0m> @jitsu/js@0.0.0 clean /Users/ildarnurislamov/Projects/onetag/libs/jitsu-js
|
|
4
|
+
[36m@jitsu/js:clean: [0m> rm -rf ./dist
|
|
5
|
+
[36m@jitsu/js:clean: [0m
|
|
@@ -90,9 +90,15 @@ function generateX509Certificate(altNames: { type: number; value: string }[]) {
|
|
|
90
90
|
|
|
91
91
|
function shutdownFunction(server): Promise<void> {
|
|
92
92
|
return new Promise<void>(resolve => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
let resolved = false;
|
|
94
|
+
const resolveIfNeeded = () => {
|
|
95
|
+
if (!resolved) {
|
|
96
|
+
resolved = true;
|
|
97
|
+
resolve();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
setTimeout(resolveIfNeeded, 5000);
|
|
101
|
+
server.close(resolveIfNeeded);
|
|
96
102
|
});
|
|
97
103
|
}
|
|
98
104
|
|
package/dist/jitsu.cjs.js
CHANGED
|
@@ -75,6 +75,7 @@ const config = {
|
|
|
75
75
|
host: null,
|
|
76
76
|
debug: false,
|
|
77
77
|
fetch: null,
|
|
78
|
+
echoEvents: false,
|
|
78
79
|
};
|
|
79
80
|
const parseQuery = (qs) => {
|
|
80
81
|
if (!qs) {
|
|
@@ -311,22 +312,81 @@ function adjustPayload(payload, config, storage) {
|
|
|
311
312
|
},
|
|
312
313
|
campaign: parseUtms(query),
|
|
313
314
|
};
|
|
314
|
-
const withContext = Object.assign(Object.assign({}, payload), { timestamp: new Date().toISOString(), sentAt: new Date().toISOString(), messageId: randomId(properties.path || (parsedUrl && parsedUrl.pathname)), context: deepMerge(context, customContext) });
|
|
315
|
+
const withContext = Object.assign(Object.assign({}, payload), { timestamp: new Date().toISOString(), sentAt: new Date().toISOString(), messageId: randomId(properties.path || (parsedUrl && parsedUrl.pathname)), writeKey: config.writeKey, context: deepMerge(context, customContext) });
|
|
315
316
|
delete withContext.meta;
|
|
316
317
|
delete withContext.options;
|
|
317
318
|
return withContext;
|
|
318
319
|
}
|
|
320
|
+
function execJs(code, event) {
|
|
321
|
+
const varName = `jitsu_event_${randomId()}`;
|
|
322
|
+
window[varName] = event;
|
|
323
|
+
const iif = `(function(){
|
|
324
|
+
${code}
|
|
325
|
+
onEvent(${varName});
|
|
326
|
+
})()`;
|
|
327
|
+
try {
|
|
328
|
+
eval(iif);
|
|
329
|
+
}
|
|
330
|
+
catch (e) {
|
|
331
|
+
console.error(`[JITSU] Error executing JS code: ${e.message}`);
|
|
332
|
+
}
|
|
333
|
+
finally {
|
|
334
|
+
delete window[varName];
|
|
335
|
+
}
|
|
336
|
+
return iif;
|
|
337
|
+
}
|
|
338
|
+
function replaceMacro(code, event) {
|
|
339
|
+
return code.replace(/{{\s*event\s*}}/g, JSON.stringify(event));
|
|
340
|
+
}
|
|
341
|
+
function insertTags(tags, event, opts = {}) {
|
|
342
|
+
const debug = opts.debug || false;
|
|
343
|
+
if (isInBrowser()) {
|
|
344
|
+
Object.values(tags).forEach(tag => {
|
|
345
|
+
if (tag.mode === "javascript") {
|
|
346
|
+
execJs(tag.code, event);
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
const codeHolder = document.createElement("span");
|
|
350
|
+
codeHolder.innerHTML = replaceMacro(tag.code, event);
|
|
351
|
+
document.body.insertAdjacentElement("beforeend", codeHolder);
|
|
352
|
+
const scripts = codeHolder.querySelectorAll("script");
|
|
353
|
+
scripts.forEach(script => {
|
|
354
|
+
const scriptClone = document.createElement("script");
|
|
355
|
+
scriptClone.type = scriptClone.type || "text/javascript";
|
|
356
|
+
if (script.hasAttribute("src")) {
|
|
357
|
+
scriptClone.src = script.src;
|
|
358
|
+
}
|
|
359
|
+
scriptClone.text = script.text;
|
|
360
|
+
if (debug) {
|
|
361
|
+
console.log(`Executing script${script.hasAttribute("src") ? ` ${script.src}` : ""}`, scriptClone.text);
|
|
362
|
+
}
|
|
363
|
+
document.head.appendChild(scriptClone);
|
|
364
|
+
document.head.removeChild(scriptClone);
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
if (debug) {
|
|
371
|
+
console.log(`insertTags: cannot insert tags in non-browser environment`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
319
375
|
function send(method, payload, jitsuConfig, store) {
|
|
376
|
+
if (jitsuConfig.echoEvents) {
|
|
377
|
+
console.log(`[JITSU] sending '${method}' event:`, payload);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
320
380
|
const url = `${jitsuConfig.host}/api/s/${method}`;
|
|
321
381
|
const fetch = jitsuConfig.fetch || globalThis.fetch;
|
|
322
382
|
if (!fetch) {
|
|
323
383
|
throw new Error("Please specify fetch function in jitsu plugin initialization, fetch isn't available in global scope");
|
|
324
384
|
}
|
|
325
|
-
const authHeader =
|
|
385
|
+
const authHeader = {};
|
|
326
386
|
const debugHeader = jitsuConfig.debug ? { "X-Enable-Debug": "true" } : {};
|
|
327
|
-
if (jitsuConfig.debug) {
|
|
328
|
-
|
|
329
|
-
}
|
|
387
|
+
// if (jitsuConfig.debug) {
|
|
388
|
+
// console.log(`[JITSU] Sending event to ${url}: `, JSON.stringify(payload, null, 2));
|
|
389
|
+
// }
|
|
330
390
|
const adjustedPayload = adjustPayload(payload, jitsuConfig, store);
|
|
331
391
|
return fetch(url, {
|
|
332
392
|
method: "POST",
|
|
@@ -335,7 +395,27 @@ function send(method, payload, jitsuConfig, store) {
|
|
|
335
395
|
})
|
|
336
396
|
.then(res => {
|
|
337
397
|
if (jitsuConfig.debug) {
|
|
338
|
-
console.
|
|
398
|
+
console.log(`[JITSU] ${url} replied ${res.status}. Original payload: `, JSON.stringify(adjustedPayload, null, 2));
|
|
399
|
+
}
|
|
400
|
+
if (res.ok) {
|
|
401
|
+
return res.text();
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
return Promise.reject(res.text());
|
|
405
|
+
}
|
|
406
|
+
})
|
|
407
|
+
.then(responseText => {
|
|
408
|
+
try {
|
|
409
|
+
const response = JSON.parse(responseText);
|
|
410
|
+
if (response.tags) {
|
|
411
|
+
if (jitsuConfig.debug) {
|
|
412
|
+
console.log(`[JITSU] Response Tags: `, JSON.stringify(response.tags, null, 2));
|
|
413
|
+
}
|
|
414
|
+
insertTags(response.tags, payload, { debug: jitsuConfig.debug });
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
catch (e) {
|
|
418
|
+
return Promise.reject(`Can't parse JSON: ${responseText}: ${e === null || e === void 0 ? void 0 : e.message}`);
|
|
339
419
|
}
|
|
340
420
|
})
|
|
341
421
|
.catch(err => {
|
|
@@ -370,8 +450,8 @@ const jitsuAnalyticsPlugin = (pluginConfig = {}) => {
|
|
|
370
450
|
if (config.debug) {
|
|
371
451
|
console.debug("Initializing Jitsu plugin with config: ", JSON.stringify(config));
|
|
372
452
|
}
|
|
373
|
-
if (!config.host) {
|
|
374
|
-
throw new Error("Please specify host variable in jitsu plugin initialization");
|
|
453
|
+
if (!config.host && !config.echoEvents) {
|
|
454
|
+
throw new Error("Please specify host variable in jitsu plugin initialization, or set echoEvents to true");
|
|
375
455
|
}
|
|
376
456
|
},
|
|
377
457
|
page: args => {
|
package/dist/jitsu.d.ts
CHANGED
|
@@ -10,10 +10,33 @@ type JitsuOptions = {
|
|
|
10
10
|
* API Host. Default value: same host as script origin
|
|
11
11
|
*/
|
|
12
12
|
host?: string;
|
|
13
|
+
/**
|
|
14
|
+
* To enable debug logging
|
|
15
|
+
*/
|
|
13
16
|
debug?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Explicitely 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
|
+
*/
|
|
14
22
|
cookieDomain?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Provide fetch implementation. It is required if you want to use Jitsu in NodeJS
|
|
25
|
+
*/
|
|
15
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
|
+
*/
|
|
16
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;
|
|
17
40
|
};
|
|
18
41
|
type PersistentStorage = {
|
|
19
42
|
getItem: (key: string, options?: any) => any;
|
package/dist/jitsu.es.js
CHANGED
|
@@ -73,6 +73,7 @@ const config = {
|
|
|
73
73
|
host: null,
|
|
74
74
|
debug: false,
|
|
75
75
|
fetch: null,
|
|
76
|
+
echoEvents: false,
|
|
76
77
|
};
|
|
77
78
|
const parseQuery = (qs) => {
|
|
78
79
|
if (!qs) {
|
|
@@ -309,22 +310,81 @@ function adjustPayload(payload, config, storage) {
|
|
|
309
310
|
},
|
|
310
311
|
campaign: parseUtms(query),
|
|
311
312
|
};
|
|
312
|
-
const withContext = Object.assign(Object.assign({}, payload), { timestamp: new Date().toISOString(), sentAt: new Date().toISOString(), messageId: randomId(properties.path || (parsedUrl && parsedUrl.pathname)), context: deepMerge(context, customContext) });
|
|
313
|
+
const withContext = Object.assign(Object.assign({}, payload), { timestamp: new Date().toISOString(), sentAt: new Date().toISOString(), messageId: randomId(properties.path || (parsedUrl && parsedUrl.pathname)), writeKey: config.writeKey, context: deepMerge(context, customContext) });
|
|
313
314
|
delete withContext.meta;
|
|
314
315
|
delete withContext.options;
|
|
315
316
|
return withContext;
|
|
316
317
|
}
|
|
318
|
+
function execJs(code, event) {
|
|
319
|
+
const varName = `jitsu_event_${randomId()}`;
|
|
320
|
+
window[varName] = event;
|
|
321
|
+
const iif = `(function(){
|
|
322
|
+
${code}
|
|
323
|
+
onEvent(${varName});
|
|
324
|
+
})()`;
|
|
325
|
+
try {
|
|
326
|
+
eval(iif);
|
|
327
|
+
}
|
|
328
|
+
catch (e) {
|
|
329
|
+
console.error(`[JITSU] Error executing JS code: ${e.message}`);
|
|
330
|
+
}
|
|
331
|
+
finally {
|
|
332
|
+
delete window[varName];
|
|
333
|
+
}
|
|
334
|
+
return iif;
|
|
335
|
+
}
|
|
336
|
+
function replaceMacro(code, event) {
|
|
337
|
+
return code.replace(/{{\s*event\s*}}/g, JSON.stringify(event));
|
|
338
|
+
}
|
|
339
|
+
function insertTags(tags, event, opts = {}) {
|
|
340
|
+
const debug = opts.debug || false;
|
|
341
|
+
if (isInBrowser()) {
|
|
342
|
+
Object.values(tags).forEach(tag => {
|
|
343
|
+
if (tag.mode === "javascript") {
|
|
344
|
+
execJs(tag.code, event);
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
const codeHolder = document.createElement("span");
|
|
348
|
+
codeHolder.innerHTML = replaceMacro(tag.code, event);
|
|
349
|
+
document.body.insertAdjacentElement("beforeend", codeHolder);
|
|
350
|
+
const scripts = codeHolder.querySelectorAll("script");
|
|
351
|
+
scripts.forEach(script => {
|
|
352
|
+
const scriptClone = document.createElement("script");
|
|
353
|
+
scriptClone.type = scriptClone.type || "text/javascript";
|
|
354
|
+
if (script.hasAttribute("src")) {
|
|
355
|
+
scriptClone.src = script.src;
|
|
356
|
+
}
|
|
357
|
+
scriptClone.text = script.text;
|
|
358
|
+
if (debug) {
|
|
359
|
+
console.log(`Executing script${script.hasAttribute("src") ? ` ${script.src}` : ""}`, scriptClone.text);
|
|
360
|
+
}
|
|
361
|
+
document.head.appendChild(scriptClone);
|
|
362
|
+
document.head.removeChild(scriptClone);
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
if (debug) {
|
|
369
|
+
console.log(`insertTags: cannot insert tags in non-browser environment`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
317
373
|
function send(method, payload, jitsuConfig, store) {
|
|
374
|
+
if (jitsuConfig.echoEvents) {
|
|
375
|
+
console.log(`[JITSU] sending '${method}' event:`, payload);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
318
378
|
const url = `${jitsuConfig.host}/api/s/${method}`;
|
|
319
379
|
const fetch = jitsuConfig.fetch || globalThis.fetch;
|
|
320
380
|
if (!fetch) {
|
|
321
381
|
throw new Error("Please specify fetch function in jitsu plugin initialization, fetch isn't available in global scope");
|
|
322
382
|
}
|
|
323
|
-
const authHeader =
|
|
383
|
+
const authHeader = {};
|
|
324
384
|
const debugHeader = jitsuConfig.debug ? { "X-Enable-Debug": "true" } : {};
|
|
325
|
-
if (jitsuConfig.debug) {
|
|
326
|
-
|
|
327
|
-
}
|
|
385
|
+
// if (jitsuConfig.debug) {
|
|
386
|
+
// console.log(`[JITSU] Sending event to ${url}: `, JSON.stringify(payload, null, 2));
|
|
387
|
+
// }
|
|
328
388
|
const adjustedPayload = adjustPayload(payload, jitsuConfig, store);
|
|
329
389
|
return fetch(url, {
|
|
330
390
|
method: "POST",
|
|
@@ -333,7 +393,27 @@ function send(method, payload, jitsuConfig, store) {
|
|
|
333
393
|
})
|
|
334
394
|
.then(res => {
|
|
335
395
|
if (jitsuConfig.debug) {
|
|
336
|
-
console.
|
|
396
|
+
console.log(`[JITSU] ${url} replied ${res.status}. Original payload: `, JSON.stringify(adjustedPayload, null, 2));
|
|
397
|
+
}
|
|
398
|
+
if (res.ok) {
|
|
399
|
+
return res.text();
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
return Promise.reject(res.text());
|
|
403
|
+
}
|
|
404
|
+
})
|
|
405
|
+
.then(responseText => {
|
|
406
|
+
try {
|
|
407
|
+
const response = JSON.parse(responseText);
|
|
408
|
+
if (response.tags) {
|
|
409
|
+
if (jitsuConfig.debug) {
|
|
410
|
+
console.log(`[JITSU] Response Tags: `, JSON.stringify(response.tags, null, 2));
|
|
411
|
+
}
|
|
412
|
+
insertTags(response.tags, payload, { debug: jitsuConfig.debug });
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
catch (e) {
|
|
416
|
+
return Promise.reject(`Can't parse JSON: ${responseText}: ${e === null || e === void 0 ? void 0 : e.message}`);
|
|
337
417
|
}
|
|
338
418
|
})
|
|
339
419
|
.catch(err => {
|
|
@@ -368,8 +448,8 @@ const jitsuAnalyticsPlugin = (pluginConfig = {}) => {
|
|
|
368
448
|
if (config.debug) {
|
|
369
449
|
console.debug("Initializing Jitsu plugin with config: ", JSON.stringify(config));
|
|
370
450
|
}
|
|
371
|
-
if (!config.host) {
|
|
372
|
-
throw new Error("Please specify host variable in jitsu plugin initialization");
|
|
451
|
+
if (!config.host && !config.echoEvents) {
|
|
452
|
+
throw new Error("Please specify host variable in jitsu plugin initialization, or set echoEvents to true");
|
|
373
453
|
}
|
|
374
454
|
},
|
|
375
455
|
page: args => {
|
package/dist/web/p.js.txt
CHANGED
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
host: null,
|
|
77
77
|
debug: false,
|
|
78
78
|
fetch: null,
|
|
79
|
+
echoEvents: false,
|
|
79
80
|
};
|
|
80
81
|
const parseQuery = (qs) => {
|
|
81
82
|
if (!qs) {
|
|
@@ -312,22 +313,81 @@
|
|
|
312
313
|
},
|
|
313
314
|
campaign: parseUtms(query),
|
|
314
315
|
};
|
|
315
|
-
const withContext = Object.assign(Object.assign({}, payload), { timestamp: new Date().toISOString(), sentAt: new Date().toISOString(), messageId: randomId(properties.path || (parsedUrl && parsedUrl.pathname)), context: deepMerge(context, customContext) });
|
|
316
|
+
const withContext = Object.assign(Object.assign({}, payload), { timestamp: new Date().toISOString(), sentAt: new Date().toISOString(), messageId: randomId(properties.path || (parsedUrl && parsedUrl.pathname)), writeKey: config.writeKey, context: deepMerge(context, customContext) });
|
|
316
317
|
delete withContext.meta;
|
|
317
318
|
delete withContext.options;
|
|
318
319
|
return withContext;
|
|
319
320
|
}
|
|
321
|
+
function execJs(code, event) {
|
|
322
|
+
const varName = `jitsu_event_${randomId()}`;
|
|
323
|
+
window[varName] = event;
|
|
324
|
+
const iif = `(function(){
|
|
325
|
+
${code}
|
|
326
|
+
onEvent(${varName});
|
|
327
|
+
})()`;
|
|
328
|
+
try {
|
|
329
|
+
eval(iif);
|
|
330
|
+
}
|
|
331
|
+
catch (e) {
|
|
332
|
+
console.error(`[JITSU] Error executing JS code: ${e.message}`);
|
|
333
|
+
}
|
|
334
|
+
finally {
|
|
335
|
+
delete window[varName];
|
|
336
|
+
}
|
|
337
|
+
return iif;
|
|
338
|
+
}
|
|
339
|
+
function replaceMacro(code, event) {
|
|
340
|
+
return code.replace(/{{\s*event\s*}}/g, JSON.stringify(event));
|
|
341
|
+
}
|
|
342
|
+
function insertTags(tags, event, opts = {}) {
|
|
343
|
+
const debug = opts.debug || false;
|
|
344
|
+
if (isInBrowser()) {
|
|
345
|
+
Object.values(tags).forEach(tag => {
|
|
346
|
+
if (tag.mode === "javascript") {
|
|
347
|
+
execJs(tag.code, event);
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
const codeHolder = document.createElement("span");
|
|
351
|
+
codeHolder.innerHTML = replaceMacro(tag.code, event);
|
|
352
|
+
document.body.insertAdjacentElement("beforeend", codeHolder);
|
|
353
|
+
const scripts = codeHolder.querySelectorAll("script");
|
|
354
|
+
scripts.forEach(script => {
|
|
355
|
+
const scriptClone = document.createElement("script");
|
|
356
|
+
scriptClone.type = scriptClone.type || "text/javascript";
|
|
357
|
+
if (script.hasAttribute("src")) {
|
|
358
|
+
scriptClone.src = script.src;
|
|
359
|
+
}
|
|
360
|
+
scriptClone.text = script.text;
|
|
361
|
+
if (debug) {
|
|
362
|
+
console.log(`Executing script${script.hasAttribute("src") ? ` ${script.src}` : ""}`, scriptClone.text);
|
|
363
|
+
}
|
|
364
|
+
document.head.appendChild(scriptClone);
|
|
365
|
+
document.head.removeChild(scriptClone);
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
if (debug) {
|
|
372
|
+
console.log(`insertTags: cannot insert tags in non-browser environment`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
320
376
|
function send(method, payload, jitsuConfig, store) {
|
|
377
|
+
if (jitsuConfig.echoEvents) {
|
|
378
|
+
console.log(`[JITSU] sending '${method}' event:`, payload);
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
321
381
|
const url = `${jitsuConfig.host}/api/s/${method}`;
|
|
322
382
|
const fetch = jitsuConfig.fetch || globalThis.fetch;
|
|
323
383
|
if (!fetch) {
|
|
324
384
|
throw new Error("Please specify fetch function in jitsu plugin initialization, fetch isn't available in global scope");
|
|
325
385
|
}
|
|
326
|
-
const authHeader =
|
|
386
|
+
const authHeader = {};
|
|
327
387
|
const debugHeader = jitsuConfig.debug ? { "X-Enable-Debug": "true" } : {};
|
|
328
|
-
if (jitsuConfig.debug) {
|
|
329
|
-
|
|
330
|
-
}
|
|
388
|
+
// if (jitsuConfig.debug) {
|
|
389
|
+
// console.log(`[JITSU] Sending event to ${url}: `, JSON.stringify(payload, null, 2));
|
|
390
|
+
// }
|
|
331
391
|
const adjustedPayload = adjustPayload(payload, jitsuConfig, store);
|
|
332
392
|
return fetch(url, {
|
|
333
393
|
method: "POST",
|
|
@@ -336,7 +396,27 @@
|
|
|
336
396
|
})
|
|
337
397
|
.then(res => {
|
|
338
398
|
if (jitsuConfig.debug) {
|
|
339
|
-
console.
|
|
399
|
+
console.log(`[JITSU] ${url} replied ${res.status}. Original payload: `, JSON.stringify(adjustedPayload, null, 2));
|
|
400
|
+
}
|
|
401
|
+
if (res.ok) {
|
|
402
|
+
return res.text();
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
return Promise.reject(res.text());
|
|
406
|
+
}
|
|
407
|
+
})
|
|
408
|
+
.then(responseText => {
|
|
409
|
+
try {
|
|
410
|
+
const response = JSON.parse(responseText);
|
|
411
|
+
if (response.tags) {
|
|
412
|
+
if (jitsuConfig.debug) {
|
|
413
|
+
console.log(`[JITSU] Response Tags: `, JSON.stringify(response.tags, null, 2));
|
|
414
|
+
}
|
|
415
|
+
insertTags(response.tags, payload, { debug: jitsuConfig.debug });
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
catch (e) {
|
|
419
|
+
return Promise.reject(`Can't parse JSON: ${responseText}: ${e === null || e === void 0 ? void 0 : e.message}`);
|
|
340
420
|
}
|
|
341
421
|
})
|
|
342
422
|
.catch(err => {
|
|
@@ -371,8 +451,8 @@
|
|
|
371
451
|
if (config.debug) {
|
|
372
452
|
console.debug("Initializing Jitsu plugin with config: ", JSON.stringify(config));
|
|
373
453
|
}
|
|
374
|
-
if (!config.host) {
|
|
375
|
-
throw new Error("Please specify host variable in jitsu plugin initialization");
|
|
454
|
+
if (!config.host && !config.echoEvents) {
|
|
455
|
+
throw new Error("Please specify host variable in jitsu plugin initialization, or set echoEvents to true");
|
|
376
456
|
}
|
|
377
457
|
},
|
|
378
458
|
page: args => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jitsu/js",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.174",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Jitsu Dev Team <dev@jitsu.com>",
|
|
6
6
|
"main": "dist/jitsu.cjs.js",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"analytics": "^0.8.1",
|
|
39
|
-
"@jitsu/protocols": "0.0.1-alpha.
|
|
39
|
+
"@jitsu/protocols": "0.0.1-alpha.174"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"clean": "rm -rf ./dist",
|
package/src/analytics-plugin.ts
CHANGED
|
@@ -12,6 +12,7 @@ const config: JitsuOptions = {
|
|
|
12
12
|
host: null,
|
|
13
13
|
debug: false,
|
|
14
14
|
fetch: null,
|
|
15
|
+
echoEvents: false,
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
export const parseQuery = (qs?: string): Record<string, string> => {
|
|
@@ -276,6 +277,7 @@ function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentSt
|
|
|
276
277
|
timestamp: new Date().toISOString(),
|
|
277
278
|
sentAt: new Date().toISOString(),
|
|
278
279
|
messageId: randomId(properties.path || (parsedUrl && parsedUrl.pathname)),
|
|
280
|
+
writeKey: config.writeKey,
|
|
279
281
|
context: deepMerge(context, customContext),
|
|
280
282
|
};
|
|
281
283
|
delete withContext.meta;
|
|
@@ -283,7 +285,70 @@ function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentSt
|
|
|
283
285
|
return withContext;
|
|
284
286
|
}
|
|
285
287
|
|
|
288
|
+
function execJs(code: string, event: any) {
|
|
289
|
+
const varName = `jitsu_event_${randomId()}`;
|
|
290
|
+
window[varName] = event;
|
|
291
|
+
const iif = `(function(){
|
|
292
|
+
${code}
|
|
293
|
+
onEvent(${varName});
|
|
294
|
+
})()`;
|
|
295
|
+
try {
|
|
296
|
+
eval(iif);
|
|
297
|
+
} catch (e) {
|
|
298
|
+
console.error(`[JITSU] Error executing JS code: ${e.message}`);
|
|
299
|
+
} finally {
|
|
300
|
+
delete window[varName];
|
|
301
|
+
}
|
|
302
|
+
return iif;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function replaceMacro(code, event) {
|
|
306
|
+
return code.replace(/{{\s*event\s*}}/g, JSON.stringify(event));
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function insertTags(
|
|
310
|
+
tags: Record<string, { mode: "javascript" | "html"; code }>,
|
|
311
|
+
event: any,
|
|
312
|
+
opts: { debug?: boolean } = {}
|
|
313
|
+
) {
|
|
314
|
+
const debug = opts.debug || false;
|
|
315
|
+
if (isInBrowser()) {
|
|
316
|
+
Object.values(tags).forEach(tag => {
|
|
317
|
+
if (tag.mode === "javascript") {
|
|
318
|
+
execJs(tag.code, event);
|
|
319
|
+
} else {
|
|
320
|
+
const codeHolder = document.createElement("span");
|
|
321
|
+
codeHolder.innerHTML = replaceMacro(tag.code, event);
|
|
322
|
+
document.body.insertAdjacentElement("beforeend", codeHolder);
|
|
323
|
+
const scripts = codeHolder.querySelectorAll("script");
|
|
324
|
+
scripts.forEach(script => {
|
|
325
|
+
const scriptClone = document.createElement("script");
|
|
326
|
+
scriptClone.type = scriptClone.type || "text/javascript";
|
|
327
|
+
if (script.hasAttribute("src")) {
|
|
328
|
+
scriptClone.src = script.src;
|
|
329
|
+
}
|
|
330
|
+
scriptClone.text = script.text;
|
|
331
|
+
if (debug) {
|
|
332
|
+
console.log(`Executing script${script.hasAttribute("src") ? ` ${script.src}` : ""}`, scriptClone.text);
|
|
333
|
+
}
|
|
334
|
+
document.head.appendChild(scriptClone);
|
|
335
|
+
document.head.removeChild(scriptClone);
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
} else {
|
|
340
|
+
if (debug) {
|
|
341
|
+
console.log(`insertTags: cannot insert tags in non-browser environment`);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
286
346
|
function send(method, payload, jitsuConfig: Required<JitsuOptions>, store: PersistentStorage): Promise<void> {
|
|
347
|
+
if (jitsuConfig.echoEvents) {
|
|
348
|
+
console.log(`[JITSU] sending '${method}' event:`, payload);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
|
|
287
352
|
const url = `${jitsuConfig.host}/api/s/${method}`;
|
|
288
353
|
const fetch = jitsuConfig.fetch || globalThis.fetch;
|
|
289
354
|
if (!fetch) {
|
|
@@ -291,12 +356,12 @@ function send(method, payload, jitsuConfig: Required<JitsuOptions>, store: Persi
|
|
|
291
356
|
"Please specify fetch function in jitsu plugin initialization, fetch isn't available in global scope"
|
|
292
357
|
);
|
|
293
358
|
}
|
|
294
|
-
const authHeader =
|
|
359
|
+
const authHeader = {};
|
|
295
360
|
const debugHeader = jitsuConfig.debug ? { "X-Enable-Debug": "true" } : {};
|
|
296
361
|
|
|
297
|
-
if (jitsuConfig.debug) {
|
|
298
|
-
|
|
299
|
-
}
|
|
362
|
+
// if (jitsuConfig.debug) {
|
|
363
|
+
// console.log(`[JITSU] Sending event to ${url}: `, JSON.stringify(payload, null, 2));
|
|
364
|
+
// }
|
|
300
365
|
const adjustedPayload = adjustPayload(payload, jitsuConfig, store);
|
|
301
366
|
return fetch(url, {
|
|
302
367
|
method: "POST",
|
|
@@ -310,11 +375,29 @@ function send(method, payload, jitsuConfig: Required<JitsuOptions>, store: Persi
|
|
|
310
375
|
})
|
|
311
376
|
.then(res => {
|
|
312
377
|
if (jitsuConfig.debug) {
|
|
313
|
-
console.
|
|
314
|
-
`
|
|
378
|
+
console.log(
|
|
379
|
+
`[JITSU] ${url} replied ${res.status}. Original payload: `,
|
|
315
380
|
JSON.stringify(adjustedPayload, null, 2)
|
|
316
381
|
);
|
|
317
382
|
}
|
|
383
|
+
if (res.ok) {
|
|
384
|
+
return res.text();
|
|
385
|
+
} else {
|
|
386
|
+
return Promise.reject(res.text());
|
|
387
|
+
}
|
|
388
|
+
})
|
|
389
|
+
.then(responseText => {
|
|
390
|
+
try {
|
|
391
|
+
const response = JSON.parse(responseText);
|
|
392
|
+
if (response.tags) {
|
|
393
|
+
if (jitsuConfig.debug) {
|
|
394
|
+
console.log(`[JITSU] Response Tags: `, JSON.stringify(response.tags, null, 2));
|
|
395
|
+
}
|
|
396
|
+
insertTags(response.tags, payload, { debug: jitsuConfig.debug });
|
|
397
|
+
}
|
|
398
|
+
} catch (e) {
|
|
399
|
+
return Promise.reject(`Can't parse JSON: ${responseText}: ${e?.message}`);
|
|
400
|
+
}
|
|
318
401
|
})
|
|
319
402
|
.catch(err => {
|
|
320
403
|
if (jitsuConfig.debug) {
|
|
@@ -352,8 +435,8 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
|
|
|
352
435
|
if (config.debug) {
|
|
353
436
|
console.debug("Initializing Jitsu plugin with config: ", JSON.stringify(config));
|
|
354
437
|
}
|
|
355
|
-
if (!config.host) {
|
|
356
|
-
throw new Error("Please specify host variable in jitsu plugin initialization");
|
|
438
|
+
if (!config.host && !config.echoEvents) {
|
|
439
|
+
throw new Error("Please specify host variable in jitsu plugin initialization, or set echoEvents to true");
|
|
357
440
|
}
|
|
358
441
|
},
|
|
359
442
|
page: args => {
|
package/src/jitsu.ts
CHANGED
|
@@ -11,10 +11,33 @@ type JitsuOptions = {
|
|
|
11
11
|
* API Host. Default value: same host as script origin
|
|
12
12
|
*/
|
|
13
13
|
host?: string;
|
|
14
|
+
/**
|
|
15
|
+
* To enable debug logging
|
|
16
|
+
*/
|
|
14
17
|
debug?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Explicitely specify cookie domain. If not set, cookie domain will be set to top level
|
|
20
|
+
* of the current domain. Example: if JS lives on "app.example.com", cookie domain will be
|
|
21
|
+
* set to ".example.com". If it lives on "example.com", cookie domain will be set to ".example.com" too
|
|
22
|
+
*/
|
|
15
23
|
cookieDomain?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Provide fetch implementation. It is required if you want to use Jitsu in NodeJS
|
|
26
|
+
*/
|
|
16
27
|
fetch?: typeof fetch;
|
|
28
|
+
/**
|
|
29
|
+
* Which runtime to use. Runtime is used for obtaining context of the event: cookes,
|
|
30
|
+
* url, etc. At the moment, Jitsu supports browser runtime and NodeJS runtime, but you
|
|
31
|
+
* can provide your own implementation.
|
|
32
|
+
*
|
|
33
|
+
* If it's not set, the runtime will be detected automatically by presense of `window` object
|
|
34
|
+
*/
|
|
17
35
|
runtime?: RuntimeFacade;
|
|
36
|
+
/**
|
|
37
|
+
* If set to true, jitsu will output events in console. In this case you don't need to set
|
|
38
|
+
* writeKey / host. It's useful for debugging development environment
|
|
39
|
+
*/
|
|
40
|
+
echoEvents?: boolean;
|
|
18
41
|
};
|
|
19
42
|
|
|
20
43
|
type PersistentStorage = {
|