@stacksee/analytics 0.9.5 → 0.9.6

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.
@@ -28,6 +28,17 @@ export interface EventContext<TTraits extends Record<string, unknown> = Record<s
28
28
  type?: string;
29
29
  os?: string;
30
30
  browser?: string;
31
+ userAgent?: string;
32
+ language?: string;
33
+ timezone?: string;
34
+ screen?: {
35
+ width?: number;
36
+ height?: number;
37
+ };
38
+ viewport?: {
39
+ width?: number;
40
+ height?: number;
41
+ };
31
42
  };
32
43
  utm?: {
33
44
  source?: string;
@@ -1,16 +1,16 @@
1
- var P = Object.defineProperty;
2
- var z = (n, t, i) => t in n ? P(n, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : n[t] = i;
3
- var p = (n, t, i) => z(n, typeof t != "symbol" ? t + "" : t, i);
4
- import { B as I } from "../base.provider-AfFL5W_P.js";
5
- import { P as _ } from "../server-DjEk1fUD.js";
6
- class A extends I {
1
+ var j = Object.defineProperty;
2
+ var q = (d, h, i) => h in d ? j(d, h, { enumerable: !0, configurable: !0, writable: !0, value: i }) : d[h] = i;
3
+ var g = (d, h, i) => q(d, typeof h != "symbol" ? h + "" : h, i);
4
+ import { B as V } from "../base.provider-AfFL5W_P.js";
5
+ import { P as Q } from "../server-DjEk1fUD.js";
6
+ class M extends V {
7
7
  constructor(i) {
8
8
  super({ debug: i.debug, enabled: i.enabled });
9
- p(this, "name", "Bento-Server");
10
- p(this, "client");
11
- p(this, "initialized", !1);
12
- p(this, "config");
13
- p(this, "currentUserEmail");
9
+ g(this, "name", "Bento-Server");
10
+ g(this, "client");
11
+ g(this, "initialized", !1);
12
+ g(this, "config");
13
+ g(this, "currentUserEmail");
14
14
  this.config = i;
15
15
  }
16
16
  async initialize() {
@@ -23,8 +23,8 @@ class A extends I {
23
23
  if (!((e = this.config.authentication) != null && e.secretKey) || typeof this.config.authentication.secretKey != "string")
24
24
  throw new Error("Bento requires authentication.secretKey");
25
25
  try {
26
- const { Analytics: r } = await import("../bento-node-sdk.esm-CWEAoj97.js"), { debug: s, enabled: a, ...o } = this.config;
27
- this.client = new r(o), this.initialized = !0, this.log("Initialized successfully", {
26
+ const { Analytics: r } = await import("../bento-node-sdk.esm-CWEAoj97.js"), { debug: s, enabled: a, ...u } = this.config;
27
+ this.client = new r(u), this.initialized = !0, this.log("Initialized successfully", {
28
28
  siteUuid: this.config.siteUuid
29
29
  });
30
30
  } catch (r) {
@@ -52,9 +52,9 @@ class A extends I {
52
52
  }), this.log("Identified user", { userId: i, email: r, traits: e });
53
53
  }
54
54
  async track(i, e) {
55
- var o, l, h, d;
55
+ var u, l, p, n;
56
56
  if (!this.isEnabled() || !this.initialized || !this.client) return;
57
- const r = ((o = e == null ? void 0 : e.user) == null ? void 0 : o.email) || this.currentUserEmail || ((l = e == null ? void 0 : e.user) == null ? void 0 : l.userId) || i.userId;
57
+ const r = ((u = e == null ? void 0 : e.user) == null ? void 0 : u.email) || this.currentUserEmail || ((l = e == null ? void 0 : e.user) == null ? void 0 : l.userId) || i.userId;
58
58
  if (!r || !r.includes("@")) {
59
59
  console.warn(
60
60
  "[Bento-Server] Skipping event - Bento requires an email address. Anonymous events are not currently supported by the Bento Node SDK. For now, use the Bento client provider for anonymous tracking. If you're using a proxy, use the hybrid pattern as described in the docs. For identified users, call identify() with a valid email before tracking events."
@@ -80,8 +80,8 @@ class A extends I {
80
80
  ...(e == null ? void 0 : e.device) && { device: e.device },
81
81
  ...(e == null ? void 0 : e.utm) && { utm: e.utm },
82
82
  site: this.config.siteUuid,
83
- ...((h = e == null ? void 0 : e.user) == null ? void 0 : h.userId) && { visitor: e.user.userId }
84
- }, a = ((d = e == null ? void 0 : e.user) == null ? void 0 : d.traits) || {};
83
+ ...((p = e == null ? void 0 : e.user) == null ? void 0 : p.userId) && { visitor: e.user.userId }
84
+ }, a = ((n = e == null ? void 0 : e.user) == null ? void 0 : n.traits) || {};
85
85
  try {
86
86
  await this.client.V1.track({
87
87
  email: r,
@@ -89,14 +89,14 @@ class A extends I {
89
89
  details: s,
90
90
  fields: a
91
91
  }), this.log("Tracked event", { event: i, context: e });
92
- } catch (g) {
93
- console.error("[Bento-Server] Failed to track event:", g);
92
+ } catch (v) {
93
+ console.error("[Bento-Server] Failed to track event:", v);
94
94
  }
95
95
  }
96
96
  pageView(i, e) {
97
- var o, l, h;
97
+ var u, l, p;
98
98
  if (!this.isEnabled() || !this.initialized || !this.client) return;
99
- const r = ((o = e == null ? void 0 : e.user) == null ? void 0 : o.email) || this.currentUserEmail;
99
+ const r = ((u = e == null ? void 0 : e.user) == null ? void 0 : u.email) || this.currentUserEmail;
100
100
  if (!r || !r.includes("@")) {
101
101
  console.warn(
102
102
  "[Bento-Server] Skipping pageView - Bento requires an email address. Anonymous events are not currently supported by the Bento Node SDK. For now, use the Bento client provider for anonymous tracking. If you're using a proxy, use the hybrid pattern as described in the docs. For identified users, call identify() with a valid email before tracking events."
@@ -119,14 +119,14 @@ class A extends I {
119
119
  },
120
120
  site: this.config.siteUuid,
121
121
  ...((l = e == null ? void 0 : e.user) == null ? void 0 : l.userId) && { visitor: e.user.userId }
122
- }, a = ((h = e == null ? void 0 : e.user) == null ? void 0 : h.traits) || {};
122
+ }, a = ((p = e == null ? void 0 : e.user) == null ? void 0 : p.traits) || {};
123
123
  this.client.V1.track({
124
124
  email: r,
125
125
  type: "$view",
126
126
  details: s,
127
127
  fields: a
128
- }).catch((d) => {
129
- console.error("[Bento-Server] Failed to track page view:", d);
128
+ }).catch((n) => {
129
+ console.error("[Bento-Server] Failed to track page view:", n);
130
130
  }), this.log("Tracked page view", { properties: i, context: e });
131
131
  }
132
132
  async reset() {
@@ -136,13 +136,13 @@ class A extends I {
136
136
  this.client = void 0, this.initialized = !1, this.log("Shutdown complete");
137
137
  }
138
138
  }
139
- class K extends I {
139
+ class N extends V {
140
140
  constructor(i) {
141
141
  super({ debug: i.debug, enabled: i.enabled });
142
- p(this, "name", "Pirsch-Server");
143
- p(this, "client");
144
- p(this, "initialized", !1);
145
- p(this, "config");
142
+ g(this, "name", "Pirsch-Server");
143
+ g(this, "client");
144
+ g(this, "initialized", !1);
145
+ g(this, "config");
146
146
  this.config = i;
147
147
  }
148
148
  async initialize() {
@@ -183,51 +183,65 @@ class K extends I {
183
183
  }), this.log("Identified user via event", { userId: i, traits: e });
184
184
  }
185
185
  async track(i, e) {
186
- var g, f, y, c, m, v, b, w, u, S, E;
186
+ var v, f, y, t, w, m, b, c, k, S, _, E, I, z, P, B, F, o, $, A, K, O;
187
187
  if (!this.isEnabled() || !this.initialized || !this.client) return;
188
- const r = e, s = ((g = r == null ? void 0 : r.device) == null ? void 0 : g.ip) || "0.0.0.0", a = ((f = r == null ? void 0 : r.server) == null ? void 0 : f.userAgent) || ((y = r == null ? void 0 : r.device) == null ? void 0 : y.userAgent) || "unknown", l = {
189
- url: ((c = e == null ? void 0 : e.page) == null ? void 0 : c.url) || ((m = e == null ? void 0 : e.page) != null && m.protocol && ((v = e == null ? void 0 : e.page) != null && v.host) && ((b = e == null ? void 0 : e.page) != null && b.path) ? `${e.page.protocol}://${e.page.host}${e.page.path}` : (w = e == null ? void 0 : e.page) != null && w.path ? `https://${this.config.hostname}${e.page.path}` : "https://event"),
188
+ const r = e, s = ((v = r == null ? void 0 : r.device) == null ? void 0 : v.ip) || "0.0.0.0", a = ((f = r == null ? void 0 : r.server) == null ? void 0 : f.userAgent) || ((y = r == null ? void 0 : r.device) == null ? void 0 : y.userAgent) || "unknown", l = {
189
+ url: ((t = e == null ? void 0 : e.page) == null ? void 0 : t.url) || ((w = e == null ? void 0 : e.page) != null && w.protocol && ((m = e == null ? void 0 : e.page) != null && m.host) && ((b = e == null ? void 0 : e.page) != null && b.path) ? `${e.page.protocol}://${e.page.host}${e.page.path}` : (c = e == null ? void 0 : e.page) != null && c.path ? `https://${this.config.hostname}${e.page.path}` : "https://event"),
190
190
  ip: s,
191
191
  user_agent: a,
192
- ...((u = e == null ? void 0 : e.page) == null ? void 0 : u.title) && { title: e.page.title },
193
- ...((S = e == null ? void 0 : e.page) == null ? void 0 : S.referrer) && { referrer: e.page.referrer }
194
- }, d = {
192
+ ...((k = e == null ? void 0 : e.page) == null ? void 0 : k.title) && { title: e.page.title },
193
+ ...((S = e == null ? void 0 : e.page) == null ? void 0 : S.referrer) && { referrer: e.page.referrer },
194
+ ...((E = (_ = e == null ? void 0 : e.device) == null ? void 0 : _.screen) == null ? void 0 : E.width) && { screen_width: e.device.screen.width },
195
+ ...((z = (I = e == null ? void 0 : e.device) == null ? void 0 : I.screen) == null ? void 0 : z.height) && { screen_height: e.device.screen.height },
196
+ ...((B = (P = e == null ? void 0 : e.device) == null ? void 0 : P.viewport) == null ? void 0 : B.width) && { sec_ch_viewport_width: String(e.device.viewport.width) },
197
+ ...((F = e == null ? void 0 : e.device) == null ? void 0 : F.language) && { accept_language: e.device.language },
198
+ ...((o = e == null ? void 0 : e.device) == null ? void 0 : o.type) && { sec_ch_ua_mobile: e.device.type === "mobile" || e.device.type === "tablet" ? "?1" : "?0" },
199
+ ...(($ = e == null ? void 0 : e.device) == null ? void 0 : $.os) && { sec_ch_ua_platform: e.device.os }
200
+ }, n = {
195
201
  ...Object.fromEntries(
196
202
  Object.entries(i.properties).filter(
197
- ([, k]) => typeof k == "string" || typeof k == "number" || typeof k == "boolean"
203
+ ([, U]) => typeof U == "string" || typeof U == "number" || typeof U == "boolean"
198
204
  )
199
205
  ),
200
206
  category: i.category,
201
207
  timestamp: String(i.timestamp || Date.now()),
202
208
  ...i.userId && { userId: i.userId },
203
209
  ...i.sessionId && { sessionId: i.sessionId },
204
- ...((E = e == null ? void 0 : e.user) == null ? void 0 : E.email) && { user_email: e.user.email }
210
+ ...((A = e == null ? void 0 : e.user) == null ? void 0 : A.email) && { user_email: e.user.email },
211
+ ...((K = e == null ? void 0 : e.device) == null ? void 0 : K.timezone) && { timezone: e.device.timezone },
212
+ ...((O = e == null ? void 0 : e.device) == null ? void 0 : O.browser) && { browser: e.device.browser }
205
213
  };
206
214
  try {
207
- await this.client.event(i.action, l, 0, d), this.log("Tracked event", { event: i, context: e });
208
- } catch (k) {
209
- console.error("[Pirsch-Server] Failed to track event:", k);
215
+ await this.client.event(i.action, l, 0, n), this.log("Tracked event", { event: i, context: e });
216
+ } catch (U) {
217
+ console.error("[Pirsch-Server] Failed to track event:", U);
210
218
  }
211
219
  }
212
220
  pageView(i, e) {
213
- var h, d, g, f, y, c, m, v, b, w;
221
+ var p, n, v, f, y, t, w, m, b, c, k, S, _, E, I, z, P, B, F;
214
222
  if (!this.isEnabled() || !this.initialized || !this.client) return;
215
- const r = e, s = ((h = r == null ? void 0 : r.device) == null ? void 0 : h.ip) || "0.0.0.0", a = ((d = r == null ? void 0 : r.server) == null ? void 0 : d.userAgent) || ((g = r == null ? void 0 : r.device) == null ? void 0 : g.userAgent) || "unknown", l = {
216
- url: ((f = e == null ? void 0 : e.page) == null ? void 0 : f.url) || ((y = e == null ? void 0 : e.page) != null && y.protocol && ((c = e == null ? void 0 : e.page) != null && c.host) && ((m = e == null ? void 0 : e.page) != null && m.path) ? `${e.page.protocol}://${e.page.host}${e.page.path}` : (v = e == null ? void 0 : e.page) != null && v.path ? `https://${this.config.hostname}${e.page.path}` : "https://pageview"),
223
+ const r = e, s = ((p = r == null ? void 0 : r.device) == null ? void 0 : p.ip) || "0.0.0.0", a = ((n = r == null ? void 0 : r.server) == null ? void 0 : n.userAgent) || ((v = r == null ? void 0 : r.device) == null ? void 0 : v.userAgent) || "unknown", l = {
224
+ url: ((f = e == null ? void 0 : e.page) == null ? void 0 : f.url) || ((y = e == null ? void 0 : e.page) != null && y.protocol && ((t = e == null ? void 0 : e.page) != null && t.host) && ((w = e == null ? void 0 : e.page) != null && w.path) ? `${e.page.protocol}://${e.page.host}${e.page.path}` : (m = e == null ? void 0 : e.page) != null && m.path ? `https://${this.config.hostname}${e.page.path}` : "https://pageview"),
217
225
  ip: s,
218
226
  user_agent: a,
219
227
  ...((b = e == null ? void 0 : e.page) == null ? void 0 : b.title) && { title: e.page.title },
220
- ...((w = e == null ? void 0 : e.page) == null ? void 0 : w.referrer) && { referrer: e.page.referrer },
228
+ ...((c = e == null ? void 0 : e.page) == null ? void 0 : c.referrer) && { referrer: e.page.referrer },
229
+ ...((S = (k = e == null ? void 0 : e.device) == null ? void 0 : k.screen) == null ? void 0 : S.width) && { screen_width: e.device.screen.width },
230
+ ...((E = (_ = e == null ? void 0 : e.device) == null ? void 0 : _.screen) == null ? void 0 : E.height) && { screen_height: e.device.screen.height },
231
+ ...((z = (I = e == null ? void 0 : e.device) == null ? void 0 : I.viewport) == null ? void 0 : z.width) && { sec_ch_viewport_width: String(e.device.viewport.width) },
232
+ ...((P = e == null ? void 0 : e.device) == null ? void 0 : P.language) && { accept_language: e.device.language },
233
+ ...((B = e == null ? void 0 : e.device) == null ? void 0 : B.type) && { sec_ch_ua_mobile: e.device.type === "mobile" || e.device.type === "tablet" ? "?1" : "?0" },
234
+ ...((F = e == null ? void 0 : e.device) == null ? void 0 : F.os) && { sec_ch_ua_platform: e.device.os },
221
235
  ...i && {
222
236
  tags: Object.fromEntries(
223
237
  Object.entries(i).filter(
224
- ([, u]) => typeof u == "string" || typeof u == "number" || typeof u == "boolean"
238
+ ([, o]) => typeof o == "string" || typeof o == "number" || typeof o == "boolean"
225
239
  )
226
240
  )
227
241
  }
228
242
  };
229
- this.client.hit(l).catch((u) => {
230
- console.error("[Pirsch-Server] Failed to track page view:", u);
243
+ this.client.hit(l).catch((o) => {
244
+ console.error("[Pirsch-Server] Failed to track page view:", o);
231
245
  }), this.log("Tracked page view", { properties: i, context: e });
232
246
  }
233
247
  async reset() {
@@ -245,20 +259,20 @@ class K extends I {
245
259
  this.client = void 0, this.initialized = !1, this.log("Shutdown complete");
246
260
  }
247
261
  }
248
- async function B(n, t, i) {
262
+ async function D(d, h, i) {
249
263
  var e, r;
250
264
  try {
251
- const s = await n.json();
265
+ const s = await d.json();
252
266
  if (!s.events || !Array.isArray(s.events))
253
267
  throw new Error("Invalid payload: missing events array");
254
- const a = i != null && i.extractIp ? i.extractIp(n) : F(n), o = i != null && i.enrichContext ? i.enrichContext(n) : {};
268
+ const a = i != null && i.extractIp ? i.extractIp(d) : R(d), u = i != null && i.enrichContext ? i.enrichContext(d) : {};
255
269
  for (const l of s.events)
256
270
  try {
257
271
  switch (l.type) {
258
272
  case "track": {
259
- const h = {
273
+ const p = {
260
274
  ...l.context,
261
- ...o,
275
+ ...u,
262
276
  device: {
263
277
  ...(e = l.context) == null ? void 0 : e.device,
264
278
  // Add IP (using type assertion for extended fields)
@@ -266,22 +280,22 @@ async function B(n, t, i) {
266
280
  ...a ? { ip: a } : {}
267
281
  }
268
282
  };
269
- await t.track(l.event.action, l.event.properties, {
283
+ await h.track(l.event.action, l.event.properties, {
270
284
  userId: l.event.userId,
271
285
  sessionId: l.event.sessionId,
272
286
  // biome-ignore lint/suspicious/noExplicitAny: Generic context forwarding requires type assertion
273
- context: h
287
+ context: p
274
288
  });
275
289
  break;
276
290
  }
277
291
  case "identify": {
278
- t.identify(l.userId, l.traits);
292
+ h.identify(l.userId, l.traits);
279
293
  break;
280
294
  }
281
295
  case "pageView": {
282
- const h = {
296
+ const p = {
283
297
  ...l.context,
284
- ...o,
298
+ ...u,
285
299
  device: {
286
300
  ...(r = l.context) == null ? void 0 : r.device,
287
301
  // biome-ignore lint/suspicious/noExplicitAny: IP field not in base device type
@@ -289,7 +303,7 @@ async function B(n, t, i) {
289
303
  ...a ? { ip: a } : {}
290
304
  }
291
305
  };
292
- t.pageView(l.properties, h);
306
+ h.pageView(l.properties, p);
293
307
  break;
294
308
  }
295
309
  case "reset":
@@ -297,16 +311,16 @@ async function B(n, t, i) {
297
311
  default:
298
312
  console.warn("[Proxy] Unknown event type:", l);
299
313
  }
300
- } catch (h) {
301
- i != null && i.onError ? i.onError(h) : console.error("[Proxy] Failed to process event:", h);
314
+ } catch (p) {
315
+ i != null && i.onError ? i.onError(p) : console.error("[Proxy] Failed to process event:", p);
302
316
  }
303
317
  } catch (s) {
304
318
  throw i != null && i.onError ? i.onError(s) : console.error("[Proxy] Failed to ingest events:", s), s;
305
319
  }
306
320
  }
307
- function F(n) {
321
+ function R(d) {
308
322
  var i;
309
- const t = [
323
+ const h = [
310
324
  "x-forwarded-for",
311
325
  "x-real-ip",
312
326
  "cf-connecting-ip",
@@ -314,26 +328,26 @@ function F(n) {
314
328
  "x-client-ip",
315
329
  "x-cluster-client-ip"
316
330
  ];
317
- for (const e of t) {
318
- const r = n.headers.get(e);
331
+ for (const e of h) {
332
+ const r = d.headers.get(e);
319
333
  if (r)
320
334
  return (i = r.split(",")[0]) == null ? void 0 : i.trim();
321
335
  }
322
336
  }
323
- function O(n, t) {
337
+ function G(d, h) {
324
338
  return async (i) => {
325
339
  try {
326
- return await B(i, n, t), new Response("OK", { status: 200 });
340
+ return await D(i, d, h), new Response("OK", { status: 200 });
327
341
  } catch (e) {
328
342
  return console.error("[Proxy] Handler error:", e), new Response("Internal Server Error", { status: 500 });
329
343
  }
330
344
  };
331
345
  }
332
346
  export {
333
- I as BaseAnalyticsProvider,
334
- A as BentoServerProvider,
335
- K as PirschServerProvider,
336
- _ as PostHogServerProvider,
337
- O as createProxyHandler,
338
- B as ingestProxyEvents
347
+ V as BaseAnalyticsProvider,
348
+ M as BentoServerProvider,
349
+ N as PirschServerProvider,
350
+ Q as PostHogServerProvider,
351
+ G as createProxyHandler,
352
+ D as ingestProxyEvents
339
353
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stacksee/analytics",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "A highly typed, provider-agnostic analytics library for TypeScript applications",
5
5
  "type": "module",
6
6
  "exports": {