@jitsu/js 1.1.0 → 1.1.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.
@@ -1,65 +1,65 @@
1
- @jitsu/js:build: cache hit, replaying output 126f0e7238465aa8
2
- @jitsu/js:build: 
3
- @jitsu/js:build: > @jitsu/js@0.0.0 build /Users/vklmn/dev2/onetag/libs/jitsu-js
4
- @jitsu/js:build: > tsc -p . && rollup -c && cp compiled/src/*.d.ts dist
5
- @jitsu/js:build: 
6
- @jitsu/js:build: 
7
- @jitsu/js:build: ./compiled/src/browser.js → dist/web/p.js.txt...
8
- @jitsu/js:build: (!) "this" has been rewritten to "undefined"
9
- @jitsu/js:build: https://rollupjs.org/troubleshooting/#error-this-is-undefined
10
- @jitsu/js:build: compiled/src/analytics-plugin.js
11
- @jitsu/js:build: 1: /* global analytics */
12
- @jitsu/js:build: 2: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
- @jitsu/js:build:  ^
14
- @jitsu/js:build: 3: function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- @jitsu/js:build: 4: return new (P || (P = Promise))(function (resolve, reject) {
16
- @jitsu/js:build: ...and 1 other occurrence
17
- @jitsu/js:build: compiled/src/destination-plugins.js
18
- @jitsu/js:build: 1: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
19
- @jitsu/js:build:  ^
20
- @jitsu/js:build: 2: function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
21
- @jitsu/js:build: 3: return new (P || (P = Promise))(function (resolve, reject) {
22
- @jitsu/js:build: ...and 1 other occurrence
23
- @jitsu/js:build: (!) Circular dependencies
24
- @jitsu/js:build: compiled/src/index.js -> compiled/src/analytics-plugin.js -> compiled/src/index.js
25
- @jitsu/js:build: compiled/src/analytics-plugin.js -> compiled/src/destination-plugins.js -> compiled/src/analytics-plugin.js
26
- @jitsu/js:build: (!) Use of eval is strongly discouraged
27
- @jitsu/js:build: https://rollupjs.org/troubleshooting/#avoiding-eval
28
- @jitsu/js:build: compiled/src/destination-plugins.js
29
- @jitsu/js:build: 75: })()`;
30
- @jitsu/js:build: 76: try {
31
- @jitsu/js:build: 77: eval(iif);
32
- @jitsu/js:build:  ^
33
- @jitsu/js:build: 78: }
34
- @jitsu/js:build: 79: catch (e) {
35
- @jitsu/js:build: created dist/web/p.js.txt in 872ms
36
- @jitsu/js:build: 
37
- @jitsu/js:build: ./compiled/src/index.js, ./compiled/src/jitsu.js, ./compiled/src/analytics-plugin.js → dist/jitsu.es.js, dist/jitsu.cjs.js...
38
- @jitsu/js:build: (!) "this" has been rewritten to "undefined"
39
- @jitsu/js:build: https://rollupjs.org/troubleshooting/#error-this-is-undefined
40
- @jitsu/js:build: compiled/src/analytics-plugin.js
41
- @jitsu/js:build: 1: /* global analytics */
42
- @jitsu/js:build: 2: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
43
- @jitsu/js:build:  ^
44
- @jitsu/js:build: 3: function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
45
- @jitsu/js:build: 4: return new (P || (P = Promise))(function (resolve, reject) {
46
- @jitsu/js:build: ...and 1 other occurrence
47
- @jitsu/js:build: compiled/src/destination-plugins.js
48
- @jitsu/js:build: 1: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
49
- @jitsu/js:build:  ^
50
- @jitsu/js:build: 2: function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
51
- @jitsu/js:build: 3: return new (P || (P = Promise))(function (resolve, reject) {
52
- @jitsu/js:build: ...and 1 other occurrence
53
- @jitsu/js:build: (!) Circular dependencies
54
- @jitsu/js:build: compiled/src/index.js -> compiled/src/analytics-plugin.js -> compiled/src/index.js
55
- @jitsu/js:build: compiled/src/analytics-plugin.js -> compiled/src/destination-plugins.js -> compiled/src/analytics-plugin.js
56
- @jitsu/js:build: (!) Use of eval is strongly discouraged
57
- @jitsu/js:build: https://rollupjs.org/troubleshooting/#avoiding-eval
58
- @jitsu/js:build: compiled/src/destination-plugins.js
59
- @jitsu/js:build: 75: })()`;
60
- @jitsu/js:build: 76: try {
61
- @jitsu/js:build: 77: eval(iif);
62
- @jitsu/js:build:  ^
63
- @jitsu/js:build: 78: }
64
- @jitsu/js:build: 79: catch (e) {
65
- @jitsu/js:build: created dist/jitsu.es.js, dist/jitsu.cjs.js in 504ms
1
+ @jitsu/js:build: cache hit, replaying output 03414e3b139b4a1c
2
+ @jitsu/js:build: 
3
+ @jitsu/js:build: > @jitsu/js@0.0.0 build /Users/vklmn/dev2/onetag/libs/jitsu-js
4
+ @jitsu/js:build: > tsc -p . && rollup -c && cp compiled/src/*.d.ts dist
5
+ @jitsu/js:build: 
6
+ @jitsu/js:build: 
7
+ @jitsu/js:build: ./compiled/src/browser.js → dist/web/p.js.txt...
8
+ @jitsu/js:build: (!) "this" has been rewritten to "undefined"
9
+ @jitsu/js:build: https://rollupjs.org/troubleshooting/#error-this-is-undefined
10
+ @jitsu/js:build: compiled/src/analytics-plugin.js
11
+ @jitsu/js:build: 1: /* global analytics */
12
+ @jitsu/js:build: 2: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ @jitsu/js:build:  ^
14
+ @jitsu/js:build: 3: function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ @jitsu/js:build: 4: return new (P || (P = Promise))(function (resolve, reject) {
16
+ @jitsu/js:build: ...and 1 other occurrence
17
+ @jitsu/js:build: compiled/src/destination-plugins.js
18
+ @jitsu/js:build: 1: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
19
+ @jitsu/js:build:  ^
20
+ @jitsu/js:build: 2: function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
21
+ @jitsu/js:build: 3: return new (P || (P = Promise))(function (resolve, reject) {
22
+ @jitsu/js:build: ...and 1 other occurrence
23
+ @jitsu/js:build: (!) Circular dependencies
24
+ @jitsu/js:build: compiled/src/index.js -> compiled/src/analytics-plugin.js -> compiled/src/index.js
25
+ @jitsu/js:build: compiled/src/analytics-plugin.js -> compiled/src/destination-plugins.js -> compiled/src/analytics-plugin.js
26
+ @jitsu/js:build: (!) Use of eval is strongly discouraged
27
+ @jitsu/js:build: https://rollupjs.org/troubleshooting/#avoiding-eval
28
+ @jitsu/js:build: compiled/src/destination-plugins.js
29
+ @jitsu/js:build: 146: })()`;
30
+ @jitsu/js:build: 147: try {
31
+ @jitsu/js:build: 148: eval(iif);
32
+ @jitsu/js:build:  ^
33
+ @jitsu/js:build: 149: }
34
+ @jitsu/js:build: 150: catch (e) {
35
+ @jitsu/js:build: created dist/web/p.js.txt in 195ms
36
+ @jitsu/js:build: 
37
+ @jitsu/js:build: ./compiled/src/index.js, ./compiled/src/jitsu.js, ./compiled/src/analytics-plugin.js → dist/jitsu.es.js, dist/jitsu.cjs.js...
38
+ @jitsu/js:build: (!) "this" has been rewritten to "undefined"
39
+ @jitsu/js:build: https://rollupjs.org/troubleshooting/#error-this-is-undefined
40
+ @jitsu/js:build: compiled/src/analytics-plugin.js
41
+ @jitsu/js:build: 1: /* global analytics */
42
+ @jitsu/js:build: 2: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
43
+ @jitsu/js:build:  ^
44
+ @jitsu/js:build: 3: function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
45
+ @jitsu/js:build: 4: return new (P || (P = Promise))(function (resolve, reject) {
46
+ @jitsu/js:build: ...and 1 other occurrence
47
+ @jitsu/js:build: compiled/src/destination-plugins.js
48
+ @jitsu/js:build: 1: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
49
+ @jitsu/js:build:  ^
50
+ @jitsu/js:build: 2: function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
51
+ @jitsu/js:build: 3: return new (P || (P = Promise))(function (resolve, reject) {
52
+ @jitsu/js:build: ...and 1 other occurrence
53
+ @jitsu/js:build: (!) Circular dependencies
54
+ @jitsu/js:build: compiled/src/index.js -> compiled/src/analytics-plugin.js -> compiled/src/index.js
55
+ @jitsu/js:build: compiled/src/analytics-plugin.js -> compiled/src/destination-plugins.js -> compiled/src/analytics-plugin.js
56
+ @jitsu/js:build: (!) Use of eval is strongly discouraged
57
+ @jitsu/js:build: https://rollupjs.org/troubleshooting/#avoiding-eval
58
+ @jitsu/js:build: compiled/src/destination-plugins.js
59
+ @jitsu/js:build: 146: })()`;
60
+ @jitsu/js:build: 147: try {
61
+ @jitsu/js:build: 148: eval(iif);
62
+ @jitsu/js:build:  ^
63
+ @jitsu/js:build: 149: }
64
+ @jitsu/js:build: 150: catch (e) {
65
+ @jitsu/js:build: created dist/jitsu.es.js, dist/jitsu.cjs.js in 133ms
@@ -1,5 +1,5 @@
1
- @jitsu/js:clean: cache hit, replaying output a45f0a4478c12277
2
- @jitsu/js:clean: 
3
- @jitsu/js:clean: > @jitsu/js@0.0.0 clean /Users/vklmn/dev2/onetag/libs/jitsu-js
4
- @jitsu/js:clean: > rm -rf ./dist
5
- @jitsu/js:clean: 
1
+ @jitsu/js:clean: cache hit, replaying output 02a6b0bcaf2c7148
2
+ @jitsu/js:clean: 
3
+ @jitsu/js:clean: > @jitsu/js@0.0.0 clean /Users/vklmn/dev2/onetag/libs/jitsu-js
4
+ @jitsu/js:clean: > rm -rf ./dist
5
+ @jitsu/js:clean: 
@@ -35,7 +35,7 @@ describe("Test Jitsu NodeJS client", () => {
35
35
  await startServer();
36
36
  try {
37
37
  const jitsu: AnalyticsInterface = jitsuAnalytics({
38
- writeKey: "test",
38
+ writeKey: "key:secret",
39
39
  host: server.baseUrl,
40
40
  debug: true,
41
41
  fetch: fetchImpl,
@@ -46,6 +46,10 @@ describe("Test Jitsu NodeJS client", () => {
46
46
  email: "test@test.com",
47
47
  });
48
48
 
49
+ await jitsu.group("testGroup", {
50
+ name: "Test Group",
51
+ });
52
+
49
53
  await jitsu.page({
50
54
  name: "test",
51
55
  environment: "nodejs",
@@ -56,14 +60,16 @@ describe("Test Jitsu NodeJS client", () => {
56
60
  },
57
61
  });
58
62
  await new Promise(resolve => setTimeout(resolve, 1000));
59
- expect(requestLog.length).toBe(3);
63
+ expect(requestLog.length).toBe(4);
60
64
  expect(requestLog[0].type).toBe("track");
61
65
  expect(requestLog[1].type).toBe("identify");
62
- expect(requestLog[2].type).toBe("page");
66
+ expect(requestLog[2].type).toBe("group");
67
+ expect(requestLog[3].type).toBe("page");
63
68
 
64
69
  const track = requestLog[0].body as AnalyticsClientEvent;
65
70
  const identify = requestLog[1].body as AnalyticsClientEvent;
66
- const page = requestLog[2].body as AnalyticsClientEvent;
71
+ const group = requestLog[2].body as AnalyticsClientEvent;
72
+ const page = requestLog[3].body as AnalyticsClientEvent;
67
73
 
68
74
  //expect(track.userId).toBe(undefined);
69
75
  expect(page.properties.name).toBe("test");
@@ -72,6 +78,11 @@ describe("Test Jitsu NodeJS client", () => {
72
78
  expect(page.userId).toBe("testUser");
73
79
  expect(identify.traits.email).toBe("test@test.com");
74
80
  expect(identify.anonymousId).toBe(page.anonymousId);
81
+ expect(group.traits.name).toBe("Test Group");
82
+ expect(group.anonymousId).toBe(page.anonymousId);
83
+ expect(group.userId).toBe("testUser");
84
+ expect(group.groupId).toBe("testGroup");
85
+
75
86
  const pagePayload = requestLog[0].body;
76
87
  console.log("pagePayload", pagePayload);
77
88
  } finally {
@@ -7,8 +7,6 @@ import ejs from "ejs";
7
7
  import * as process from "process";
8
8
  import * as console from "console";
9
9
  import { AnalyticsClientEvent, AnalyticsInterface } from "@jitsu/protocols/analytics.d";
10
- import type { AnalyticsCore } from "@segment/analytics-next/src/core/analytics/interfaces";
11
- import { response } from "express";
12
10
 
13
11
  test.use({
14
12
  ignoreHTTPSErrors: true,
@@ -116,6 +114,7 @@ const generateTestEvents = async () => {
116
114
  await analytics.identify("userId2", { email: "john.doe2@gmail.com", caseName: "basic-identify" });
117
115
  // jitsu must extract traits even from 'id' object
118
116
  await analytics.identify({ email: "john.doe3@gmail.com", caseName: "identify-without-user-id" });
117
+ await analytics.group("group1", { name: "Group 1", caseName: "basic-group" });
119
118
  await analytics.page({ caseName: "page-without-name", context: { page: { title: "Synthetic Title" } } });
120
119
  await analytics.page("test-page", { caseName: "page-with-name" });
121
120
  await analytics.track("testEvent", { caseName: "track-with-name" });
@@ -10,6 +10,7 @@ export type DestinationDescriptor = {
10
10
  id: string;
11
11
  destinationType: string;
12
12
  credentials: any;
13
+ options: any;
13
14
  deviceOptions: DeviceOptions;
14
15
  };
15
16
  export type AnalyticsPluginDescriptor = {
@@ -10,4 +10,8 @@ export type CommonDestinationCredentials = {
10
10
  export type TagDestinationCredentials = {
11
11
  code: string;
12
12
  } & CommonDestinationCredentials;
13
+ export type LogRocketDestinationCredentials = {
14
+ appId: string;
15
+ } & CommonDestinationCredentials;
16
+ export type LogRocket = any;
13
17
  export declare const internalDestinationPlugins: Record<string, InternalPlugin<any>>;
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export declare const emptyAnalytics: {
5
5
  page: () => Promise<void>;
6
6
  user: () => {};
7
7
  identify: () => Promise<{}>;
8
+ group: () => Promise<{}>;
8
9
  reset: () => Promise<{}>;
9
10
  };
10
11
  export declare function jitsuAnalytics(opts: JitsuOptions): AnalyticsInterface;
package/dist/jitsu.cjs.js CHANGED
@@ -67,6 +67,49 @@ function analyticsLib() {
67
67
  return ke(_objectSpread2(_objectSpread2({}, defaultSettings), opts));
68
68
  }
69
69
 
70
+ function findScript(src) {
71
+ const scripts = Array.prototype.slice.call(window.document.querySelectorAll("script"));
72
+ return scripts.find(s => s.src === src);
73
+ }
74
+ function loadScript(src, attributes) {
75
+ const found = findScript(src);
76
+ if (found !== undefined) {
77
+ const status = found === null || found === void 0 ? void 0 : found.getAttribute("status");
78
+ if (status === "loaded") {
79
+ return Promise.resolve(found);
80
+ }
81
+ if (status === "loading") {
82
+ return new Promise((resolve, reject) => {
83
+ found.addEventListener("load", () => resolve(found));
84
+ found.addEventListener("error", err => reject(err));
85
+ });
86
+ }
87
+ }
88
+ return new Promise((resolve, reject) => {
89
+ var _a;
90
+ const script = window.document.createElement("script");
91
+ script.type = "text/javascript";
92
+ script.src = src;
93
+ script.async = true;
94
+ script.setAttribute("status", "loading");
95
+ for (const [k, v] of Object.entries(attributes !== null && attributes !== void 0 ? attributes : {})) {
96
+ script.setAttribute(k, v);
97
+ }
98
+ script.onload = () => {
99
+ script.onerror = script.onload = null;
100
+ script.setAttribute("status", "loaded");
101
+ resolve(script);
102
+ };
103
+ script.onerror = () => {
104
+ script.onerror = script.onload = null;
105
+ script.setAttribute("status", "error");
106
+ reject(new Error(`Failed to load ${src}`));
107
+ };
108
+ const tag = window.document.getElementsByTagName("script")[0];
109
+ (_a = tag.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(script, tag);
110
+ });
111
+ }
112
+
70
113
  var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
71
114
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
72
115
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -95,6 +138,76 @@ const tagPlugin = {
95
138
  });
96
139
  },
97
140
  };
141
+ function getLogRocketState() {
142
+ return window["__jitsuLrState"] || "fresh";
143
+ }
144
+ function setLogRocketState(s) {
145
+ window["__jitsuLrState"] = s;
146
+ }
147
+ function getLogRocketQueue() {
148
+ return window["__jitsuLrQueue"] || (window["__jitsuLrQueue"] = []);
149
+ }
150
+ function flushLogRocketQueue(lr) {
151
+ const queue = getLogRocketQueue();
152
+ while (queue.length > 0) {
153
+ const method = queue.shift();
154
+ try {
155
+ const res = method(lr);
156
+ if (res) {
157
+ res.catch(e => console.warn(`Async LogRocket method failed: ${e.message}`, e));
158
+ }
159
+ }
160
+ catch (e) {
161
+ console.warn(`LogRocket method failed: ${e.message}`, e);
162
+ }
163
+ }
164
+ }
165
+ function initLogrocketIfNeeded(appId) {
166
+ return __awaiter$1(this, void 0, void 0, function* () {
167
+ if (getLogRocketState() !== "fresh") {
168
+ return;
169
+ }
170
+ setLogRocketState("loading");
171
+ loadScript(`https://cdn.lr-ingest.io/LogRocket.min.js`, { crossOrigin: "anonymous" })
172
+ .then(() => {
173
+ if (window["LogRocket"]) {
174
+ try {
175
+ window["LogRocket"].init(appId);
176
+ }
177
+ catch (e) {
178
+ console.warn(`LogRocket (id=${appId}) init failed: ${e.message}`, e);
179
+ setLogRocketState("failed");
180
+ }
181
+ setLogRocketState("loaded");
182
+ flushLogRocketQueue(window["LogRocket"]);
183
+ }
184
+ })
185
+ .catch(e => {
186
+ console.warn(`LogRocket (id=${appId}) init failed: ${e.message}`, e);
187
+ setLogRocketState("failed");
188
+ });
189
+ });
190
+ }
191
+ const logrocketPlugin = {
192
+ id: "logrocket",
193
+ handle(config, payload) {
194
+ return __awaiter$1(this, void 0, void 0, function* () {
195
+ if (!applyFilters(payload, config)) {
196
+ return;
197
+ }
198
+ initLogrocketIfNeeded(config.appId);
199
+ const action = logRocket => {
200
+ if (payload.type === "identify" && payload.userId) {
201
+ logRocket.identify(payload.userId, payload.traits || {});
202
+ }
203
+ };
204
+ getLogRocketQueue().push(action);
205
+ if (getLogRocketState() === "loaded") {
206
+ flushLogRocketQueue(window["LogRocket"]);
207
+ }
208
+ });
209
+ },
210
+ };
98
211
  function insertTags(code, event, opts = {}) {
99
212
  let tag;
100
213
  try {
@@ -157,50 +270,11 @@ function replaceMacro(code, event) {
157
270
  }
158
271
  const internalDestinationPlugins = {
159
272
  [tagPlugin.id]: tagPlugin,
273
+ [logrocketPlugin.id]: logrocketPlugin,
160
274
  };
161
275
 
162
- function findScript(src) {
163
- const scripts = Array.prototype.slice.call(window.document.querySelectorAll("script"));
164
- return scripts.find(s => s.src === src);
165
- }
166
- function loadScript(src, attributes) {
167
- const found = findScript(src);
168
- if (found !== undefined) {
169
- const status = found === null || found === void 0 ? void 0 : found.getAttribute("status");
170
- if (status === "loaded") {
171
- return Promise.resolve(found);
172
- }
173
- if (status === "loading") {
174
- return new Promise((resolve, reject) => {
175
- found.addEventListener("load", () => resolve(found));
176
- found.addEventListener("error", err => reject(err));
177
- });
178
- }
179
- }
180
- return new Promise((resolve, reject) => {
181
- var _a;
182
- const script = window.document.createElement("script");
183
- script.type = "text/javascript";
184
- script.src = src;
185
- script.async = true;
186
- script.setAttribute("status", "loading");
187
- for (const [k, v] of Object.entries(attributes !== null && attributes !== void 0 ? attributes : {})) {
188
- script.setAttribute(k, v);
189
- }
190
- script.onload = () => {
191
- script.onerror = script.onload = null;
192
- script.setAttribute("status", "loaded");
193
- resolve(script);
194
- };
195
- script.onerror = () => {
196
- script.onerror = script.onload = null;
197
- script.setAttribute("status", "error");
198
- reject(new Error(`Failed to load ${src}`));
199
- };
200
- const tag = window.document.getElementsByTagName("script")[0];
201
- (_a = tag.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(script, tag);
202
- });
203
- }
276
+ var name = "@jitsu/js";
277
+ var version = "0.0.0";
204
278
 
205
279
  /* global analytics */
206
280
  var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
@@ -220,6 +294,8 @@ const config = {
220
294
  debug: false,
221
295
  fetch: null,
222
296
  echoEvents: false,
297
+ cookieDomain: undefined,
298
+ runtime: undefined,
223
299
  };
224
300
  const parseQuery = (qs) => {
225
301
  if (!qs) {
@@ -437,13 +513,13 @@ function adjustPayload(payload, config, storage) {
437
513
  const referrer = runtime.referrer();
438
514
  const context = {
439
515
  library: {
440
- name: "jitsu-js",
441
- version: "1.0.0",
516
+ name: name,
517
+ version: version,
442
518
  },
443
519
  userAgent: runtime.userAgent(),
444
520
  locale: runtime.language(),
445
521
  screen: runtime.screen(),
446
- traits: payload.type != "identify" ? Object.assign({}, (restoreTraits(storage) || {})) : undefined,
522
+ traits: payload.type != "identify" && payload.type != "group" ? Object.assign({}, (restoreTraits(storage) || {})) : undefined,
447
523
  page: {
448
524
  path: properties.path || (parsedUrl && parsedUrl.pathname),
449
525
  referrer: referrer,
@@ -452,11 +528,11 @@ function adjustPayload(payload, config, storage) {
452
528
  search: properties.search || (parsedUrl && parsedUrl.search),
453
529
  title: properties.title || runtime.pageTitle(),
454
530
  url: properties.url || url,
455
- enconding: properties.enconding || runtime.documentEncoding(),
531
+ encoding: properties.encoding || runtime.documentEncoding(),
456
532
  },
457
533
  campaign: parseUtms(query),
458
534
  };
459
- 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) });
535
+ const withContext = Object.assign(Object.assign({}, payload), { timestamp: new Date().toISOString(), sentAt: new Date().toISOString(), messageId: randomId(properties.path || (parsedUrl && parsedUrl.pathname)), writeKey: validateWriteKey(config.writeKey), context: deepMerge(context, customContext) });
460
536
  delete withContext.meta;
461
537
  delete withContext.options;
462
538
  return withContext;
@@ -465,12 +541,11 @@ function processDestinations(destinations, method, event, debug, analyticsInstan
465
541
  return __awaiter(this, void 0, void 0, function* () {
466
542
  const promises = [];
467
543
  for (const destination of destinations) {
544
+ const credentials = Object.assign(Object.assign({}, destination.credentials), destination.options);
468
545
  if (destination.deviceOptions.type === "internal-plugin") {
469
546
  const plugin = internalDestinationPlugins[destination.deviceOptions.name];
470
547
  if (plugin) {
471
548
  try {
472
- //to support old versions, where credentials were stored in root
473
- const credentials = destination.credentials || destination;
474
549
  promises.push(plugin.handle(credentials, event));
475
550
  }
476
551
  catch (e) {
@@ -490,7 +565,7 @@ function processDestinations(destinations, method, event, debug, analyticsInstan
490
565
  else {
491
566
  let pluginInstance;
492
567
  try {
493
- pluginInstance = (typeof plugin === "function" ? plugin : plugin.init)(destination.credentials);
568
+ pluginInstance = (typeof plugin === "function" ? plugin : plugin.init)(credentials);
494
569
  }
495
570
  catch (e) {
496
571
  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);
@@ -518,6 +593,15 @@ function processDestinations(destinations, method, event, debug, analyticsInstan
518
593
  }
519
594
  });
520
595
  }
596
+ function validateWriteKey(writeKey) {
597
+ if (writeKey) {
598
+ const [, secret] = writeKey.split(":", 2);
599
+ if (!secret) {
600
+ throw new Error(`Legacy write key detected - ${writeKey}! This format doesn't work anymore, it should be 'key:secret'. Please download a new key from Jitsu UI`);
601
+ }
602
+ }
603
+ return writeKey;
604
+ }
521
605
  function send(method, payload, jitsuConfig, instance, store) {
522
606
  if (jitsuConfig.echoEvents) {
523
607
  console.log(`[JITSU] sending '${method}' event:`, payload);
@@ -533,7 +617,7 @@ function send(method, payload, jitsuConfig, instance, store) {
533
617
  // console.log(`[JITSU] Sending event to ${url}: `, JSON.stringify(payload, null, 2));
534
618
  // }
535
619
  const adjustedPayload = adjustPayload(payload, jitsuConfig, store);
536
- const authHeader = adjustedPayload.writeKey ? { "X-Write-Key": adjustedPayload.writeKey } : {};
620
+ const authHeader = config.writeKey ? { "X-Write-Key": validateWriteKey(config.writeKey) } : {};
537
621
  return fetch(url, {
538
622
  method: "POST",
539
623
  headers: Object.assign(Object.assign({ "Content-Type": "application/json" }, authHeader), debugHeader),
@@ -560,7 +644,7 @@ function send(method, payload, jitsuConfig, instance, store) {
560
644
  }
561
645
  if (response.destinations) {
562
646
  if (jitsuConfig.debug) {
563
- console.log(`[JITSU] Processing device destianations: `, JSON.stringify(response.destinations, null, 2));
647
+ console.log(`[JITSU] Processing device destinations: `, JSON.stringify(response.destinations, null, 2));
564
648
  }
565
649
  return processDestinations(response.destinations, method, adjustedPayload, !!jitsuConfig.debug, instance);
566
650
  }
@@ -589,9 +673,10 @@ const jitsuAnalyticsPlugin = (pluginConfig = {}) => {
589
673
  persistentStorage.removeItem(key);
590
674
  },
591
675
  });
676
+ const instanceConfig = Object.assign(Object.assign({}, config), pluginConfig);
592
677
  return {
593
678
  name: "jitsu",
594
- config: Object.assign(Object.assign({}, config), pluginConfig),
679
+ config: instanceConfig,
595
680
  initialize: args => {
596
681
  const { config } = args;
597
682
  if (config.debug) {
@@ -619,6 +704,16 @@ const jitsuAnalyticsPlugin = (pluginConfig = {}) => {
619
704
  //clear storage cache
620
705
  Object.keys(storageCache).forEach(key => delete storageCache[key]);
621
706
  },
707
+ methods: {
708
+ //analytics doesn't support group as a base method, so we need to add it manually
709
+ group(groupId, traits, options, callback) {
710
+ const analyticsInstance = this.instance;
711
+ const user = analyticsInstance.user();
712
+ const userId = (options === null || options === void 0 ? void 0 : options.userId) || (user === null || user === void 0 ? void 0 : user.userId);
713
+ const anonymousId = (options === null || options === void 0 ? void 0 : options.anonymousId) || (user === null || user === void 0 ? void 0 : user.anonymousId);
714
+ return send("group", Object.assign(Object.assign({ type: "group", groupId, traits }, (anonymousId ? { anonymousId } : {})), (userId ? { userId } : {})), instanceConfig, analyticsInstance, cachingStorageWrapper(analyticsInstance.storage));
715
+ },
716
+ },
622
717
  };
623
718
  };
624
719
  function getSeed() {
@@ -671,6 +766,7 @@ const emptyAnalytics = {
671
766
  page: () => Promise.resolve(),
672
767
  user: () => ({}),
673
768
  identify: () => Promise.resolve({}),
769
+ group: () => Promise.resolve({}),
674
770
  reset: () => Promise.resolve({}),
675
771
  };
676
772
  function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
@@ -689,7 +785,14 @@ function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
689
785
  return originalPage(...args);
690
786
  }
691
787
  };
692
- return analytics;
788
+ return Object.assign(Object.assign({}, analytics), { group(groupId, traits, options, callback) {
789
+ for (const plugin of Object.values(analytics.plugins)) {
790
+ if (plugin["group"]) {
791
+ plugin["group"](groupId, traits, options, callback);
792
+ }
793
+ }
794
+ return Promise.resolve({});
795
+ } });
693
796
  }
694
797
  function jitsuAnalytics(opts) {
695
798
  const inBrowser = isInBrowser();