@stacksee/analytics 0.13.0 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_commonjsHelpers-DaMA6jEr.js +8 -0
- package/dist/{bento-node-sdk.esm-CWEAoj97.js → bento-node-sdk.esm-CT4oS3Kp.js} +1 -1
- package/dist/providers/client.js +8 -7
- package/dist/providers/emitkit/server.d.ts +5 -0
- package/dist/providers/pirsch/client.d.ts +5 -0
- package/dist/providers/pirsch/server.d.ts +38 -4
- package/dist/providers/server.js +344 -271
- package/dist/web-D-ZwlgeQ.js +2034 -0
- package/package.json +1 -1
- package/dist/_commonjsHelpers-B4e78b8K.js +0 -28
- package/dist/axios-0_CwElpL.js +0 -1820
- package/dist/index-zS7gy63J.js +0 -829
- package/dist/web-imCcOhDC.js +0 -220
package/dist/providers/server.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { B } from "../base.provider-AfFL5W_P.js";
|
|
5
|
-
import { P as
|
|
6
|
-
class
|
|
1
|
+
var U = Object.defineProperty;
|
|
2
|
+
var F = (d, u, i) => u in d ? U(d, u, { enumerable: !0, configurable: !0, writable: !0, value: i }) : d[u] = i;
|
|
3
|
+
var c = (d, u, i) => F(d, typeof u != "symbol" ? u + "" : u, i);
|
|
4
|
+
import { B as y } from "../base.provider-AfFL5W_P.js";
|
|
5
|
+
import { P as H } from "../server-DjEk1fUD.js";
|
|
6
|
+
class O extends y {
|
|
7
7
|
constructor(i) {
|
|
8
8
|
super({ debug: i.debug, enabled: i.enabled });
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
c(this, "name", "Bento-Server");
|
|
10
|
+
c(this, "client");
|
|
11
|
+
c(this, "initialized", !1);
|
|
12
|
+
c(this, "config");
|
|
13
|
+
c(this, "currentUserEmail");
|
|
14
14
|
this.config = i;
|
|
15
15
|
}
|
|
16
16
|
async initialize() {
|
|
@@ -23,8 +23,8 @@ class H extends B {
|
|
|
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-
|
|
27
|
-
this.client = new r(
|
|
26
|
+
const { Analytics: r } = await import("../bento-node-sdk.esm-CT4oS3Kp.js"), { debug: s, enabled: a, ...t } = this.config;
|
|
27
|
+
this.client = new r(t), this.initialized = !0, this.log("Initialized successfully", {
|
|
28
28
|
siteUuid: this.config.siteUuid
|
|
29
29
|
});
|
|
30
30
|
} catch (r) {
|
|
@@ -46,25 +46,25 @@ class H extends B {
|
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
this.currentUserEmail = r;
|
|
49
|
-
const
|
|
50
|
-
|
|
49
|
+
const s = e ? { ...e } : {};
|
|
50
|
+
s.email = void 0, this.client.V1.addSubscriber({
|
|
51
51
|
email: r,
|
|
52
|
-
fields:
|
|
53
|
-
}).catch((
|
|
54
|
-
console.error("[Bento-Server] Failed to identify user:",
|
|
52
|
+
fields: s
|
|
53
|
+
}).catch((a) => {
|
|
54
|
+
console.error("[Bento-Server] Failed to identify user:", a);
|
|
55
55
|
}), this.log("Identified user", { userId: i, email: r, traits: e });
|
|
56
56
|
}
|
|
57
57
|
async track(i, e) {
|
|
58
|
-
var
|
|
58
|
+
var t, h, l, n;
|
|
59
59
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
60
|
-
const r = ((
|
|
60
|
+
const r = ((t = e == null ? void 0 : e.user) == null ? void 0 : t.email) || this.currentUserEmail || ((h = e == null ? void 0 : e.user) == null ? void 0 : h.userId) || i.userId;
|
|
61
61
|
if (!r || !r.includes("@")) {
|
|
62
62
|
console.warn(
|
|
63
63
|
"[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."
|
|
64
64
|
);
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
|
-
const
|
|
67
|
+
const s = {
|
|
68
68
|
...i.properties,
|
|
69
69
|
category: i.category,
|
|
70
70
|
timestamp: i.timestamp || Date.now(),
|
|
@@ -83,30 +83,30 @@ class H extends B {
|
|
|
83
83
|
...(e == null ? void 0 : e.device) && { device: e.device },
|
|
84
84
|
...(e == null ? void 0 : e.utm) && { utm: e.utm },
|
|
85
85
|
site: this.config.siteUuid,
|
|
86
|
-
...((
|
|
87
|
-
},
|
|
86
|
+
...((l = e == null ? void 0 : e.user) == null ? void 0 : l.userId) && { visitor: e.user.userId }
|
|
87
|
+
}, a = ((n = e == null ? void 0 : e.user) == null ? void 0 : n.traits) || {};
|
|
88
88
|
try {
|
|
89
89
|
await this.client.V1.track({
|
|
90
90
|
email: r,
|
|
91
91
|
type: `$${i.action}`,
|
|
92
|
-
details:
|
|
93
|
-
fields:
|
|
92
|
+
details: s,
|
|
93
|
+
fields: a
|
|
94
94
|
}), this.log("Tracked event", { event: i, context: e });
|
|
95
|
-
} catch (
|
|
96
|
-
console.error("[Bento-Server] Failed to track event:",
|
|
95
|
+
} catch (o) {
|
|
96
|
+
console.error("[Bento-Server] Failed to track event:", o);
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
pageView(i, e) {
|
|
100
|
-
var
|
|
100
|
+
var t, h, l;
|
|
101
101
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
102
|
-
const r = ((
|
|
102
|
+
const r = ((t = e == null ? void 0 : e.user) == null ? void 0 : t.email) || this.currentUserEmail;
|
|
103
103
|
if (!r || !r.includes("@")) {
|
|
104
104
|
console.warn(
|
|
105
105
|
"[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."
|
|
106
106
|
);
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
|
-
const
|
|
109
|
+
const s = {
|
|
110
110
|
...i,
|
|
111
111
|
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
112
112
|
...(e == null ? void 0 : e.page) && {
|
|
@@ -121,15 +121,15 @@ class H extends B {
|
|
|
121
121
|
}
|
|
122
122
|
},
|
|
123
123
|
site: this.config.siteUuid,
|
|
124
|
-
...((
|
|
125
|
-
},
|
|
124
|
+
...((h = e == null ? void 0 : e.user) == null ? void 0 : h.userId) && { visitor: e.user.userId }
|
|
125
|
+
}, a = ((l = e == null ? void 0 : e.user) == null ? void 0 : l.traits) || {};
|
|
126
126
|
this.client.V1.track({
|
|
127
127
|
email: r,
|
|
128
128
|
type: "$view",
|
|
129
|
-
details:
|
|
130
|
-
fields:
|
|
131
|
-
}).catch((
|
|
132
|
-
console.error("[Bento-Server] Failed to track page view:",
|
|
129
|
+
details: s,
|
|
130
|
+
fields: a
|
|
131
|
+
}).catch((n) => {
|
|
132
|
+
console.error("[Bento-Server] Failed to track page view:", n);
|
|
133
133
|
}), this.log("Tracked page view", { properties: i, context: e });
|
|
134
134
|
}
|
|
135
135
|
async reset() {
|
|
@@ -139,186 +139,257 @@ class H extends B {
|
|
|
139
139
|
this.client = void 0, this.initialized = !1, this.log("Shutdown complete");
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
-
|
|
142
|
+
const T = "https://api.pirsch.io", K = 1e4;
|
|
143
|
+
class j extends y {
|
|
143
144
|
constructor(i) {
|
|
144
145
|
super({ debug: i.debug, enabled: i.enabled });
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
c(this, "name", "Pirsch-Server");
|
|
147
|
+
c(this, "initialized", !1);
|
|
148
|
+
c(this, "config");
|
|
149
|
+
c(this, "accessToken", "");
|
|
150
|
+
c(this, "tokenExpiresAt", null);
|
|
151
|
+
c(this, "isAccessKey", !1);
|
|
149
152
|
this.config = i;
|
|
150
153
|
}
|
|
151
154
|
async initialize() {
|
|
152
|
-
if (
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
)
|
|
162
|
-
try {
|
|
163
|
-
const { Pirsch: e } = await import("../index-zS7gy63J.js").then((l) => l.i), { debug: r, enabled: a, ...s } = this.config;
|
|
164
|
-
this.client = new e(s), this.initialized = !0, this.log("Initialized successfully", {
|
|
155
|
+
if (this.isEnabled() && !this.initialized) {
|
|
156
|
+
if (!this.config.hostname || typeof this.config.hostname != "string")
|
|
157
|
+
throw new Error("Pirsch requires a hostname");
|
|
158
|
+
if (!this.config.clientSecret || typeof this.config.clientSecret != "string")
|
|
159
|
+
throw new Error("Pirsch requires a clientSecret (or access key)");
|
|
160
|
+
if (this.isAccessKey = this.config.clientSecret.startsWith("pa_"), !this.isAccessKey && !this.config.clientId)
|
|
161
|
+
throw new Error(
|
|
162
|
+
"Pirsch requires a clientId when using OAuth authentication (clientSecret doesn't start with 'pa_'). Either provide a clientId or use an access key (starts with 'pa_') as clientSecret."
|
|
163
|
+
);
|
|
164
|
+
this.isAccessKey && (this.accessToken = this.config.clientSecret), this.initialized = !0, this.log("Initialized successfully", {
|
|
165
165
|
hostname: this.config.hostname,
|
|
166
|
-
authMode:
|
|
166
|
+
authMode: this.isAccessKey ? "access-key" : "oauth"
|
|
167
167
|
});
|
|
168
|
-
} catch (e) {
|
|
169
|
-
throw console.error(
|
|
170
|
-
"[Pirsch-Server] Failed to initialize. Make sure pirsch-sdk is installed:",
|
|
171
|
-
e
|
|
172
|
-
), e;
|
|
173
168
|
}
|
|
174
169
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
};
|
|
189
|
-
this.client.event("user_identified", r, 0, a).catch((s) => {
|
|
190
|
-
console.error("[Pirsch-Server] Failed to track identify event:", s);
|
|
191
|
-
}), this.log("Identified user via event", { userId: i, traits: e });
|
|
170
|
+
/**
|
|
171
|
+
* Fetch with timeout using AbortController
|
|
172
|
+
*/
|
|
173
|
+
async fetchWithTimeout(i, e, r) {
|
|
174
|
+
const s = new AbortController(), a = r ?? this.config.timeout ?? K, t = setTimeout(() => s.abort(), a);
|
|
175
|
+
try {
|
|
176
|
+
return await fetch(i, {
|
|
177
|
+
...e,
|
|
178
|
+
signal: s.signal
|
|
179
|
+
});
|
|
180
|
+
} finally {
|
|
181
|
+
clearTimeout(t);
|
|
182
|
+
}
|
|
192
183
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (
|
|
198
|
-
this.
|
|
199
|
-
|
|
184
|
+
/**
|
|
185
|
+
* Ensure we have a valid access token (for OAuth mode)
|
|
186
|
+
*/
|
|
187
|
+
async ensureToken() {
|
|
188
|
+
if (this.isAccessKey)
|
|
189
|
+
return this.accessToken;
|
|
190
|
+
if (this.accessToken && this.tokenExpiresAt && /* @__PURE__ */ new Date() < new Date(this.tokenExpiresAt.getTime() - 6e4))
|
|
191
|
+
return this.accessToken;
|
|
192
|
+
try {
|
|
193
|
+
const i = await this.fetchWithTimeout(
|
|
194
|
+
`${T}/api/v1/token`,
|
|
200
195
|
{
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
196
|
+
method: "POST",
|
|
197
|
+
headers: { "Content-Type": "application/json" },
|
|
198
|
+
body: JSON.stringify({
|
|
199
|
+
client_id: this.config.clientId,
|
|
200
|
+
client_secret: this.config.clientSecret
|
|
201
|
+
})
|
|
204
202
|
}
|
|
205
203
|
);
|
|
206
|
-
|
|
204
|
+
if (!i.ok) {
|
|
205
|
+
const r = await i.text();
|
|
206
|
+
throw new Error(`Failed to get Pirsch token: ${i.status} ${r}`);
|
|
207
|
+
}
|
|
208
|
+
const e = await i.json();
|
|
209
|
+
return this.accessToken = e.access_token, this.tokenExpiresAt = new Date(e.expires_at), this.log("OAuth token refreshed", { expiresAt: e.expires_at }), this.accessToken;
|
|
210
|
+
} catch (i) {
|
|
211
|
+
throw console.error("[Pirsch-Server] Failed to refresh token:", i), i;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Make an authenticated request to Pirsch API
|
|
216
|
+
*/
|
|
217
|
+
async request(i, e, r = !0) {
|
|
218
|
+
const s = await this.ensureToken();
|
|
219
|
+
try {
|
|
220
|
+
const a = await this.fetchWithTimeout(
|
|
221
|
+
`${T}${i}`,
|
|
222
|
+
{
|
|
223
|
+
method: "POST",
|
|
224
|
+
headers: {
|
|
225
|
+
"Content-Type": "application/json",
|
|
226
|
+
Authorization: `Bearer ${s}`
|
|
227
|
+
},
|
|
228
|
+
body: JSON.stringify(e)
|
|
229
|
+
}
|
|
230
|
+
);
|
|
231
|
+
if (a.status === 401 && r && !this.isAccessKey)
|
|
232
|
+
return this.accessToken = "", this.tokenExpiresAt = null, this.request(i, e, !1);
|
|
233
|
+
if (!a.ok) {
|
|
234
|
+
const t = await a.text();
|
|
235
|
+
throw new Error(`Pirsch API error: ${a.status} ${t}`);
|
|
236
|
+
}
|
|
237
|
+
} catch (a) {
|
|
238
|
+
throw a instanceof Error && a.name === "AbortError" ? new Error(
|
|
239
|
+
`Pirsch request timeout after ${this.config.timeout ?? K}ms`
|
|
240
|
+
) : a;
|
|
207
241
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Filter object to only include scalar values (string, number, boolean)
|
|
245
|
+
*/
|
|
246
|
+
filterScalars(i) {
|
|
247
|
+
return Object.fromEntries(
|
|
248
|
+
Object.entries(i).filter(
|
|
249
|
+
([, e]) => typeof e == "string" || typeof e == "number" || typeof e == "boolean"
|
|
250
|
+
)
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Convert object values to strings for Pirsch event_meta
|
|
255
|
+
* Pirsch API requires event_meta to be a single dimension object of string values
|
|
256
|
+
*/
|
|
257
|
+
toStringRecord(i) {
|
|
258
|
+
return Object.fromEntries(
|
|
259
|
+
Object.entries(i).filter(
|
|
260
|
+
([, e]) => e != null && typeof e != "object"
|
|
261
|
+
).map(([e, r]) => [e, String(r)])
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Build a Pirsch hit from context
|
|
266
|
+
*/
|
|
267
|
+
buildHit(i) {
|
|
268
|
+
var t, h, l, n, o, p, g, f, m, v, w, b, k, E, _, S, I, A, z, P;
|
|
269
|
+
const e = i, r = ((t = e == null ? void 0 : e.device) == null ? void 0 : t.ip) || ((h = e == null ? void 0 : e.server) == null ? void 0 : h.ip), s = ((l = e == null ? void 0 : e.server) == null ? void 0 : l.userAgent) || ((n = e == null ? void 0 : e.device) == null ? void 0 : n.userAgent);
|
|
270
|
+
return !r || !s ? null : {
|
|
271
|
+
url: ((o = i == null ? void 0 : i.page) == null ? void 0 : o.url) || ((p = i == null ? void 0 : i.page) != null && p.protocol && ((g = i == null ? void 0 : i.page) != null && g.host) && ((f = i == null ? void 0 : i.page) != null && f.path) ? `${i.page.protocol}://${i.page.host}${i.page.path}` : (m = i == null ? void 0 : i.page) != null && m.path ? `https://${this.config.hostname}${i.page.path}` : `https://${this.config.hostname}`),
|
|
272
|
+
ip: r,
|
|
211
273
|
user_agent: s,
|
|
212
|
-
...((
|
|
213
|
-
...((
|
|
214
|
-
...((
|
|
215
|
-
screen_width:
|
|
274
|
+
...((v = i == null ? void 0 : i.page) == null ? void 0 : v.title) && { title: i.page.title },
|
|
275
|
+
...((w = i == null ? void 0 : i.page) == null ? void 0 : w.referrer) && { referrer: i.page.referrer },
|
|
276
|
+
...((k = (b = i == null ? void 0 : i.device) == null ? void 0 : b.screen) == null ? void 0 : k.width) && {
|
|
277
|
+
screen_width: i.device.screen.width
|
|
216
278
|
},
|
|
217
|
-
...((
|
|
218
|
-
screen_height:
|
|
279
|
+
...((_ = (E = i == null ? void 0 : i.device) == null ? void 0 : E.screen) == null ? void 0 : _.height) && {
|
|
280
|
+
screen_height: i.device.screen.height
|
|
219
281
|
},
|
|
220
|
-
...((
|
|
221
|
-
sec_ch_viewport_width: String(
|
|
282
|
+
...((I = (S = i == null ? void 0 : i.device) == null ? void 0 : S.viewport) == null ? void 0 : I.width) && {
|
|
283
|
+
sec_ch_viewport_width: String(i.device.viewport.width)
|
|
222
284
|
},
|
|
223
|
-
...((A =
|
|
224
|
-
accept_language:
|
|
285
|
+
...((A = i == null ? void 0 : i.device) == null ? void 0 : A.language) && {
|
|
286
|
+
accept_language: i.device.language
|
|
225
287
|
},
|
|
226
|
-
...((
|
|
227
|
-
sec_ch_ua_mobile:
|
|
288
|
+
...((z = i == null ? void 0 : i.device) == null ? void 0 : z.type) && {
|
|
289
|
+
sec_ch_ua_mobile: i.device.type === "mobile" || i.device.type === "tablet" ? "?1" : "?0"
|
|
228
290
|
},
|
|
229
|
-
...((
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
291
|
+
...((P = i == null ? void 0 : i.device) == null ? void 0 : P.os) && { sec_ch_ua_platform: i.device.os },
|
|
292
|
+
...this.config.disableBotFilter && { disable_bot_filter: !0 }
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
identify(i, e) {
|
|
296
|
+
if (!this.isEnabled() || !this.initialized) return;
|
|
297
|
+
const r = {
|
|
298
|
+
url: `https://${this.config.hostname}/identify`,
|
|
299
|
+
ip: "0.0.0.0",
|
|
300
|
+
user_agent: "stacksee-analytics",
|
|
301
|
+
...this.config.disableBotFilter && { disable_bot_filter: !0 }
|
|
302
|
+
}, s = this.toStringRecord({
|
|
303
|
+
userId: i,
|
|
304
|
+
...e
|
|
305
|
+
}), a = {
|
|
306
|
+
...r,
|
|
307
|
+
event_name: "user_identified",
|
|
308
|
+
event_duration: 0,
|
|
309
|
+
event_meta: s,
|
|
310
|
+
non_interactive: !0
|
|
311
|
+
// Synthetic event shouldn't affect bounce rate
|
|
312
|
+
};
|
|
313
|
+
this.request("/api/v1/event", a).catch((t) => {
|
|
314
|
+
console.error("[Pirsch-Server] Failed to track identify event:", t);
|
|
315
|
+
}), this.log("Identified user via event", { userId: i, traits: e });
|
|
316
|
+
}
|
|
317
|
+
async track(i, e) {
|
|
318
|
+
var h, l, n, o;
|
|
319
|
+
if (!this.isEnabled() || !this.initialized) return;
|
|
320
|
+
const r = this.buildHit(e);
|
|
321
|
+
if (!r) {
|
|
322
|
+
this.log("Skipping event - missing required IP or user-agent", {
|
|
323
|
+
event: i.action
|
|
324
|
+
});
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
const s = this.toStringRecord({
|
|
328
|
+
...i.properties,
|
|
236
329
|
category: i.category,
|
|
237
|
-
timestamp:
|
|
330
|
+
timestamp: i.timestamp || Date.now(),
|
|
238
331
|
...i.userId && { userId: i.userId },
|
|
239
332
|
...i.sessionId && { sessionId: i.sessionId },
|
|
240
|
-
...((
|
|
241
|
-
...((
|
|
242
|
-
...((
|
|
333
|
+
...((h = e == null ? void 0 : e.user) == null ? void 0 : h.email) && { user_email: e.user.email },
|
|
334
|
+
...((l = e == null ? void 0 : e.device) == null ? void 0 : l.timezone) && { timezone: e.device.timezone },
|
|
335
|
+
...((n = e == null ? void 0 : e.device) == null ? void 0 : n.browser) && { browser: e.device.browser }
|
|
336
|
+
}), a = ((o = i.properties) == null ? void 0 : o.non_interactive) === !0, t = {
|
|
337
|
+
...r,
|
|
338
|
+
event_name: i.action,
|
|
339
|
+
event_duration: 0,
|
|
340
|
+
event_meta: s,
|
|
341
|
+
...a && { non_interactive: !0 }
|
|
243
342
|
};
|
|
244
343
|
try {
|
|
245
|
-
await this.
|
|
246
|
-
} catch (
|
|
247
|
-
console.error("[Pirsch-Server] Failed to track event:",
|
|
344
|
+
await this.request("/api/v1/event", t), this.log("Tracked event", { event: i.action });
|
|
345
|
+
} catch (p) {
|
|
346
|
+
console.error("[Pirsch-Server] Failed to track event:", p);
|
|
248
347
|
}
|
|
249
348
|
}
|
|
250
349
|
pageView(i, e) {
|
|
251
|
-
var
|
|
252
|
-
if (!this.isEnabled() || !this.initialized
|
|
253
|
-
const r =
|
|
254
|
-
if (!
|
|
255
|
-
this.log(
|
|
256
|
-
"Skipping pageView - missing required IP or user-agent from context",
|
|
257
|
-
{
|
|
258
|
-
hasIp: !!a,
|
|
259
|
-
hasUserAgent: !!s
|
|
260
|
-
}
|
|
261
|
-
);
|
|
350
|
+
var s;
|
|
351
|
+
if (!this.isEnabled() || !this.initialized) return;
|
|
352
|
+
const r = this.buildHit(e);
|
|
353
|
+
if (!r) {
|
|
354
|
+
this.log("Skipping pageView - missing required IP or user-agent");
|
|
262
355
|
return;
|
|
263
356
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
user_agent: s,
|
|
268
|
-
...((b = e == null ? void 0 : e.page) == null ? void 0 : b.title) && { title: e.page.title },
|
|
269
|
-
...((E = e == null ? void 0 : e.page) == null ? void 0 : E.referrer) && { referrer: e.page.referrer },
|
|
270
|
-
...((k = (I = e == null ? void 0 : e.device) == null ? void 0 : I.screen) == null ? void 0 : k.width) && {
|
|
271
|
-
screen_width: e.device.screen.width
|
|
272
|
-
},
|
|
273
|
-
...((S = (_ = e == null ? void 0 : e.device) == null ? void 0 : _.screen) == null ? void 0 : S.height) && {
|
|
274
|
-
screen_height: e.device.screen.height
|
|
275
|
-
},
|
|
276
|
-
...((P = (z = e == null ? void 0 : e.device) == null ? void 0 : z.viewport) == null ? void 0 : P.width) && {
|
|
277
|
-
sec_ch_viewport_width: String(e.device.viewport.width)
|
|
278
|
-
},
|
|
279
|
-
...((U = e == null ? void 0 : e.device) == null ? void 0 : U.language) && {
|
|
280
|
-
accept_language: e.device.language
|
|
281
|
-
},
|
|
282
|
-
...((K = e == null ? void 0 : e.device) == null ? void 0 : K.type) && {
|
|
283
|
-
sec_ch_ua_mobile: e.device.type === "mobile" || e.device.type === "tablet" ? "?1" : "?0"
|
|
284
|
-
},
|
|
285
|
-
...((A = e == null ? void 0 : e.device) == null ? void 0 : A.os) && { sec_ch_ua_platform: e.device.os },
|
|
286
|
-
...i && {
|
|
287
|
-
tags: Object.fromEntries(
|
|
288
|
-
Object.entries(i).filter(
|
|
289
|
-
([, v]) => typeof v == "string" || typeof v == "number" || typeof v == "boolean"
|
|
290
|
-
)
|
|
291
|
-
)
|
|
292
|
-
}
|
|
293
|
-
};
|
|
294
|
-
this.client.hit(n).catch((v) => {
|
|
295
|
-
console.error("[Pirsch-Server] Failed to track page view:", v);
|
|
296
|
-
}), this.log("Tracked page view", { properties: i, context: e });
|
|
357
|
+
i && Object.keys(i).length > 0 && (r.tags = this.filterScalars(i)), this.request("/api/v1/hit", r).catch((a) => {
|
|
358
|
+
console.error("[Pirsch-Server] Failed to track page view:", a);
|
|
359
|
+
}), this.log("Tracked page view", { path: (s = e == null ? void 0 : e.page) == null ? void 0 : s.path });
|
|
297
360
|
}
|
|
298
361
|
async reset() {
|
|
299
|
-
if (!this.isEnabled() || !this.initialized
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
362
|
+
if (!this.isEnabled() || !this.initialized) return;
|
|
363
|
+
const e = {
|
|
364
|
+
...{
|
|
365
|
+
url: `https://${this.config.hostname}/session-reset`,
|
|
366
|
+
ip: "0.0.0.0",
|
|
367
|
+
user_agent: "stacksee-analytics",
|
|
368
|
+
...this.config.disableBotFilter && { disable_bot_filter: !0 }
|
|
369
|
+
},
|
|
370
|
+
event_name: "session_reset",
|
|
371
|
+
event_duration: 0,
|
|
372
|
+
event_meta: {},
|
|
373
|
+
non_interactive: !0
|
|
374
|
+
// Synthetic event shouldn't affect bounce rate
|
|
304
375
|
};
|
|
305
|
-
await this.
|
|
306
|
-
console.error("[Pirsch-Server] Failed to track session reset:",
|
|
376
|
+
await this.request("/api/v1/event", e).catch((r) => {
|
|
377
|
+
console.error("[Pirsch-Server] Failed to track session reset:", r);
|
|
307
378
|
}), this.log("Reset user session");
|
|
308
379
|
}
|
|
309
380
|
async shutdown() {
|
|
310
|
-
this.
|
|
381
|
+
this.accessToken = "", this.tokenExpiresAt = null, this.initialized = !1, this.log("Shutdown complete");
|
|
311
382
|
}
|
|
312
383
|
}
|
|
313
|
-
class
|
|
384
|
+
class N extends y {
|
|
314
385
|
constructor(i) {
|
|
315
386
|
super({ debug: i.debug, enabled: i.enabled });
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
387
|
+
c(this, "name", "EmitKit-Server");
|
|
388
|
+
c(this, "client");
|
|
389
|
+
c(this, "initialized", !1);
|
|
390
|
+
c(this, "config");
|
|
391
|
+
c(this, "currentUserId");
|
|
392
|
+
c(this, "currentUserEmail");
|
|
322
393
|
this.config = i;
|
|
323
394
|
}
|
|
324
395
|
async initialize() {
|
|
@@ -330,7 +401,9 @@ class G extends B {
|
|
|
330
401
|
);
|
|
331
402
|
try {
|
|
332
403
|
const { EmitKit: i } = await import("../index-CBs091W0.js");
|
|
333
|
-
this.client = new i(this.config.apiKey
|
|
404
|
+
this.client = new i(this.config.apiKey, {
|
|
405
|
+
...this.config.timeout && { timeout: this.config.timeout }
|
|
406
|
+
}), this.initialized = !0, this.log("Initialized successfully");
|
|
334
407
|
} catch (i) {
|
|
335
408
|
throw console.error(
|
|
336
409
|
"[EmitKit-Server] Failed to initialize. Make sure @emitkit/js is installed:",
|
|
@@ -344,32 +417,32 @@ class G extends B {
|
|
|
344
417
|
this.currentUserId = i;
|
|
345
418
|
const r = (e == null ? void 0 : e.email) || i;
|
|
346
419
|
r != null && r.includes("@") && (this.currentUserEmail = r);
|
|
347
|
-
const
|
|
348
|
-
i &&
|
|
420
|
+
const s = [];
|
|
421
|
+
i && s.push(i), r && r !== i && s.push(r), e != null && e.username && typeof e.username == "string" && s.push(e.username), this.client.identify({
|
|
349
422
|
user_id: i,
|
|
350
423
|
properties: e || {},
|
|
351
|
-
aliases:
|
|
352
|
-
}).then((
|
|
353
|
-
var
|
|
424
|
+
aliases: s.length > 0 ? s : void 0
|
|
425
|
+
}).then((a) => {
|
|
426
|
+
var t, h, l, n, o;
|
|
354
427
|
this.log("Identified user", {
|
|
355
428
|
userId: i,
|
|
356
429
|
email: r,
|
|
357
|
-
identityId:
|
|
358
|
-
aliasesCreated: ((
|
|
359
|
-
aliasesFailed: ((
|
|
360
|
-
}), (
|
|
430
|
+
identityId: a.data.id,
|
|
431
|
+
aliasesCreated: ((h = (t = a.data.aliases) == null ? void 0 : t.created) == null ? void 0 : h.length) || 0,
|
|
432
|
+
aliasesFailed: ((n = (l = a.data.aliases) == null ? void 0 : l.failed) == null ? void 0 : n.length) || 0
|
|
433
|
+
}), (o = a.data.aliases) != null && o.failed && a.data.aliases.failed.length > 0 && console.warn(
|
|
361
434
|
"[EmitKit-Server] Some aliases failed to create:",
|
|
362
|
-
|
|
435
|
+
a.data.aliases.failed
|
|
363
436
|
);
|
|
364
|
-
}).catch((
|
|
365
|
-
console.error("[EmitKit-Server] Failed to identify user:",
|
|
437
|
+
}).catch((a) => {
|
|
438
|
+
console.error("[EmitKit-Server] Failed to identify user:", a);
|
|
366
439
|
});
|
|
367
440
|
}
|
|
368
441
|
async track(i, e) {
|
|
369
|
-
var
|
|
442
|
+
var o, p;
|
|
370
443
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
371
|
-
const r = ((
|
|
372
|
-
...
|
|
444
|
+
const r = ((o = e == null ? void 0 : e.user) == null ? void 0 : o.email) || ((p = e == null ? void 0 : e.user) == null ? void 0 : p.userId) || i.userId || this.currentUserEmail || this.currentUserId, s = this.formatEventTitle(i.action), { __emitkit_channel: a, ...t } = i.properties || {}, h = {
|
|
445
|
+
...t,
|
|
373
446
|
category: i.category,
|
|
374
447
|
timestamp: i.timestamp || Date.now(),
|
|
375
448
|
...i.sessionId && { sessionId: i.sessionId },
|
|
@@ -387,37 +460,37 @@ class G extends B {
|
|
|
387
460
|
...(e == null ? void 0 : e.device) && { device: e.device },
|
|
388
461
|
...(e == null ? void 0 : e.utm) && { utm: e.utm },
|
|
389
462
|
...(e == null ? void 0 : e.server) && { server: e.server }
|
|
390
|
-
},
|
|
391
|
-
i.category &&
|
|
392
|
-
const
|
|
463
|
+
}, l = [];
|
|
464
|
+
i.category && l.push(i.category), t != null && t.tags && Array.isArray(t.tags) && t.tags.every((g) => typeof g == "string") && l.push(...t.tags);
|
|
465
|
+
const n = this.resolveChannelName(i);
|
|
393
466
|
try {
|
|
394
|
-
const
|
|
395
|
-
channelName:
|
|
396
|
-
title:
|
|
467
|
+
const g = await this.client.events.create({
|
|
468
|
+
channelName: n,
|
|
469
|
+
title: s,
|
|
397
470
|
description: this.getEventDescription(i, e),
|
|
398
471
|
icon: this.getEventIcon(i.category),
|
|
399
|
-
tags:
|
|
400
|
-
metadata:
|
|
472
|
+
tags: l.length > 0 ? l : void 0,
|
|
473
|
+
metadata: h,
|
|
401
474
|
userId: r || null,
|
|
402
475
|
notify: this.config.notify ?? !0,
|
|
403
476
|
displayAs: this.config.displayAs || "notification",
|
|
404
477
|
source: "stacksee-analytics"
|
|
405
478
|
});
|
|
406
479
|
this.log("Tracked event", {
|
|
407
|
-
eventId:
|
|
480
|
+
eventId: g.data.id,
|
|
408
481
|
action: i.action,
|
|
409
482
|
userId: r,
|
|
410
|
-
channelName:
|
|
483
|
+
channelName: n
|
|
411
484
|
});
|
|
412
|
-
} catch (
|
|
413
|
-
throw console.error("[EmitKit-Server] Failed to track event:",
|
|
485
|
+
} catch (g) {
|
|
486
|
+
throw console.error("[EmitKit-Server] Failed to track event:", g), g;
|
|
414
487
|
}
|
|
415
488
|
}
|
|
416
489
|
pageView(i, e) {
|
|
417
|
-
var
|
|
490
|
+
var n, o, p;
|
|
418
491
|
if (!this.isEnabled() || !this.initialized || !this.client) return;
|
|
419
|
-
const r = ((
|
|
420
|
-
...
|
|
492
|
+
const r = ((n = e == null ? void 0 : e.user) == null ? void 0 : n.email) || ((o = e == null ? void 0 : e.user) == null ? void 0 : o.userId) || this.currentUserEmail || this.currentUserId, { __emitkit_channel: s, ...a } = i || {}, t = {
|
|
493
|
+
...a,
|
|
421
494
|
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
422
495
|
...(e == null ? void 0 : e.page) && {
|
|
423
496
|
page: {
|
|
@@ -433,33 +506,33 @@ class G extends B {
|
|
|
433
506
|
...(e == null ? void 0 : e.device) && { device: e.device },
|
|
434
507
|
...(e == null ? void 0 : e.utm) && { utm: e.utm },
|
|
435
508
|
...(e == null ? void 0 : e.server) && { server: e.server }
|
|
436
|
-
},
|
|
509
|
+
}, h = {
|
|
437
510
|
action: "page_view",
|
|
438
511
|
category: "navigation",
|
|
439
512
|
properties: i || {}
|
|
440
|
-
},
|
|
513
|
+
}, l = this.resolveChannelName(h);
|
|
441
514
|
this.client.events.create({
|
|
442
|
-
channelName:
|
|
515
|
+
channelName: l,
|
|
443
516
|
title: "Page View",
|
|
444
|
-
description: ((
|
|
517
|
+
description: ((p = e == null ? void 0 : e.page) == null ? void 0 : p.path) || "User viewed a page",
|
|
445
518
|
icon: "👁️",
|
|
446
519
|
tags: ["page_view", "navigation"],
|
|
447
|
-
metadata:
|
|
520
|
+
metadata: t,
|
|
448
521
|
userId: r || null,
|
|
449
522
|
notify: !1,
|
|
450
523
|
// Don't notify for page views by default
|
|
451
524
|
displayAs: "message",
|
|
452
525
|
source: "stacksee-analytics"
|
|
453
|
-
}).then((
|
|
454
|
-
var
|
|
526
|
+
}).then((g) => {
|
|
527
|
+
var f;
|
|
455
528
|
this.log("Tracked page view", {
|
|
456
|
-
eventId:
|
|
457
|
-
path: (
|
|
529
|
+
eventId: g.data.id,
|
|
530
|
+
path: (f = e == null ? void 0 : e.page) == null ? void 0 : f.path,
|
|
458
531
|
userId: r,
|
|
459
|
-
channelName:
|
|
532
|
+
channelName: l
|
|
460
533
|
});
|
|
461
|
-
}).catch((
|
|
462
|
-
console.error("[EmitKit-Server] Failed to track page view:",
|
|
534
|
+
}).catch((g) => {
|
|
535
|
+
console.error("[EmitKit-Server] Failed to track page view:", g);
|
|
463
536
|
});
|
|
464
537
|
}
|
|
465
538
|
async reset() {
|
|
@@ -482,8 +555,8 @@ class G extends B {
|
|
|
482
555
|
* Generate a description for the event
|
|
483
556
|
*/
|
|
484
557
|
getEventDescription(i, e) {
|
|
485
|
-
var
|
|
486
|
-
return (
|
|
558
|
+
var s;
|
|
559
|
+
return (s = i.properties) != null && s.description && typeof i.properties.description == "string" ? i.properties.description : {
|
|
487
560
|
engagement: "User interaction event",
|
|
488
561
|
user: "User lifecycle event",
|
|
489
562
|
navigation: "Navigation event",
|
|
@@ -516,85 +589,85 @@ class G extends B {
|
|
|
516
589
|
if ((r = i.properties) != null && r.__emitkit_channel && typeof i.properties.__emitkit_channel == "string")
|
|
517
590
|
return i.properties.__emitkit_channel;
|
|
518
591
|
if (this.config.categoryChannelMap && i.category) {
|
|
519
|
-
const
|
|
520
|
-
if (
|
|
521
|
-
return
|
|
592
|
+
const s = this.config.categoryChannelMap[i.category];
|
|
593
|
+
if (s)
|
|
594
|
+
return s;
|
|
522
595
|
}
|
|
523
596
|
return e || this.config.channelName || "general";
|
|
524
597
|
}
|
|
525
598
|
}
|
|
526
|
-
async function
|
|
527
|
-
var e, r,
|
|
599
|
+
async function B(d, u, i) {
|
|
600
|
+
var e, r, s, a;
|
|
528
601
|
try {
|
|
529
|
-
const
|
|
530
|
-
if (!
|
|
602
|
+
const t = await d.json();
|
|
603
|
+
if (!t.events || !Array.isArray(t.events))
|
|
531
604
|
throw new Error("Invalid payload: missing events array");
|
|
532
|
-
const
|
|
533
|
-
for (const
|
|
605
|
+
const h = i != null && i.extractIp ? i.extractIp(d) : $(d), l = d.headers.get("user-agent"), n = i != null && i.enrichContext ? i.enrichContext(d) : {};
|
|
606
|
+
for (const o of t.events)
|
|
534
607
|
try {
|
|
535
|
-
switch (
|
|
608
|
+
switch (o.type) {
|
|
536
609
|
case "track": {
|
|
537
|
-
const
|
|
538
|
-
...
|
|
539
|
-
...
|
|
610
|
+
const p = {
|
|
611
|
+
...o.context,
|
|
612
|
+
...n,
|
|
540
613
|
server: {
|
|
541
|
-
...(e =
|
|
542
|
-
...typeof (
|
|
543
|
-
...
|
|
614
|
+
...(e = o.context) == null ? void 0 : e.server,
|
|
615
|
+
...typeof (n == null ? void 0 : n.server) == "object" && n.server !== null ? n.server : {},
|
|
616
|
+
...l ? { userAgent: l } : {}
|
|
544
617
|
},
|
|
545
618
|
device: {
|
|
546
|
-
...(r =
|
|
547
|
-
...
|
|
619
|
+
...(r = o.context) == null ? void 0 : r.device,
|
|
620
|
+
...h ? { ip: h } : {}
|
|
548
621
|
}
|
|
549
622
|
};
|
|
550
623
|
await u.track(
|
|
551
|
-
|
|
624
|
+
o.event.action,
|
|
552
625
|
// biome-ignore lint/suspicious/noExplicitAny: Properties from JSON cannot be type-checked against TEventMap at compile time
|
|
553
|
-
|
|
626
|
+
o.event.properties,
|
|
554
627
|
{
|
|
555
|
-
userId:
|
|
556
|
-
sessionId:
|
|
557
|
-
context:
|
|
628
|
+
userId: o.event.userId,
|
|
629
|
+
sessionId: o.event.sessionId,
|
|
630
|
+
context: p
|
|
558
631
|
}
|
|
559
632
|
);
|
|
560
633
|
break;
|
|
561
634
|
}
|
|
562
635
|
case "identify": {
|
|
563
|
-
u.identify(
|
|
636
|
+
u.identify(o.userId, o.traits);
|
|
564
637
|
break;
|
|
565
638
|
}
|
|
566
639
|
case "pageView": {
|
|
567
|
-
const
|
|
568
|
-
...
|
|
569
|
-
...
|
|
640
|
+
const p = {
|
|
641
|
+
...o.context,
|
|
642
|
+
...n,
|
|
570
643
|
server: {
|
|
571
|
-
...(
|
|
572
|
-
...typeof (
|
|
573
|
-
...
|
|
644
|
+
...(s = o.context) == null ? void 0 : s.server,
|
|
645
|
+
...typeof (n == null ? void 0 : n.server) == "object" && n.server !== null ? n.server : {},
|
|
646
|
+
...l ? { userAgent: l } : {}
|
|
574
647
|
},
|
|
575
648
|
device: {
|
|
576
|
-
...(
|
|
577
|
-
...
|
|
649
|
+
...(a = o.context) == null ? void 0 : a.device,
|
|
650
|
+
...h ? { ip: h } : {}
|
|
578
651
|
}
|
|
579
652
|
};
|
|
580
|
-
u.pageView(
|
|
581
|
-
context:
|
|
653
|
+
u.pageView(o.properties, {
|
|
654
|
+
context: p
|
|
582
655
|
});
|
|
583
656
|
break;
|
|
584
657
|
}
|
|
585
658
|
case "reset":
|
|
586
659
|
break;
|
|
587
660
|
default:
|
|
588
|
-
console.warn("[Proxy] Unknown event type:",
|
|
661
|
+
console.warn("[Proxy] Unknown event type:", o);
|
|
589
662
|
}
|
|
590
|
-
} catch (
|
|
591
|
-
i != null && i.onError ? i.onError(
|
|
663
|
+
} catch (p) {
|
|
664
|
+
i != null && i.onError ? i.onError(p) : console.error("[Proxy] Failed to process event:", p);
|
|
592
665
|
}
|
|
593
|
-
} catch (
|
|
594
|
-
throw i != null && i.onError ? i.onError(
|
|
666
|
+
} catch (t) {
|
|
667
|
+
throw i != null && i.onError ? i.onError(t) : console.error("[Proxy] Failed to ingest events:", t), t;
|
|
595
668
|
}
|
|
596
669
|
}
|
|
597
|
-
function
|
|
670
|
+
function $(d) {
|
|
598
671
|
var i;
|
|
599
672
|
const u = [
|
|
600
673
|
"x-forwarded-for",
|
|
@@ -605,26 +678,26 @@ function T(t) {
|
|
|
605
678
|
"x-cluster-client-ip"
|
|
606
679
|
];
|
|
607
680
|
for (const e of u) {
|
|
608
|
-
const r =
|
|
681
|
+
const r = d.headers.get(e);
|
|
609
682
|
if (r)
|
|
610
683
|
return (i = r.split(",")[0]) == null ? void 0 : i.trim();
|
|
611
684
|
}
|
|
612
685
|
}
|
|
613
|
-
function
|
|
686
|
+
function V(d, u) {
|
|
614
687
|
return async (i) => {
|
|
615
688
|
try {
|
|
616
|
-
return await
|
|
689
|
+
return await B(i, d, u), new Response("OK", { status: 200 });
|
|
617
690
|
} catch (e) {
|
|
618
691
|
return console.error("[Proxy] Handler error:", e), new Response("Internal Server Error", { status: 500 });
|
|
619
692
|
}
|
|
620
693
|
};
|
|
621
694
|
}
|
|
622
695
|
export {
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
696
|
+
y as BaseAnalyticsProvider,
|
|
697
|
+
O as BentoServerProvider,
|
|
698
|
+
N as EmitKitServerProvider,
|
|
699
|
+
j as PirschServerProvider,
|
|
700
|
+
H as PostHogServerProvider,
|
|
701
|
+
V as createProxyHandler,
|
|
702
|
+
B as ingestProxyEvents
|
|
630
703
|
};
|