autotel-subscribers 4.0.0
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/LICENSE +21 -0
- package/README.md +669 -0
- package/dist/amplitude.cjs +2486 -0
- package/dist/amplitude.cjs.map +1 -0
- package/dist/amplitude.d.cts +49 -0
- package/dist/amplitude.d.ts +49 -0
- package/dist/amplitude.js +2463 -0
- package/dist/amplitude.js.map +1 -0
- package/dist/event-subscriber-base-CnF3V56W.d.cts +182 -0
- package/dist/event-subscriber-base-CnF3V56W.d.ts +182 -0
- package/dist/factories.cjs +16660 -0
- package/dist/factories.cjs.map +1 -0
- package/dist/factories.d.cts +304 -0
- package/dist/factories.d.ts +304 -0
- package/dist/factories.js +16624 -0
- package/dist/factories.js.map +1 -0
- package/dist/index.cjs +16575 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +179 -0
- package/dist/index.d.ts +179 -0
- package/dist/index.js +16539 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware.cjs +220 -0
- package/dist/middleware.cjs.map +1 -0
- package/dist/middleware.d.cts +227 -0
- package/dist/middleware.d.ts +227 -0
- package/dist/middleware.js +208 -0
- package/dist/middleware.js.map +1 -0
- package/dist/mixpanel.cjs +2940 -0
- package/dist/mixpanel.cjs.map +1 -0
- package/dist/mixpanel.d.cts +47 -0
- package/dist/mixpanel.d.ts +47 -0
- package/dist/mixpanel.js +2932 -0
- package/dist/mixpanel.js.map +1 -0
- package/dist/posthog.cjs +4115 -0
- package/dist/posthog.cjs.map +1 -0
- package/dist/posthog.d.cts +299 -0
- package/dist/posthog.d.ts +299 -0
- package/dist/posthog.js +4113 -0
- package/dist/posthog.js.map +1 -0
- package/dist/segment.cjs +6822 -0
- package/dist/segment.cjs.map +1 -0
- package/dist/segment.d.cts +49 -0
- package/dist/segment.d.ts +49 -0
- package/dist/segment.js +6794 -0
- package/dist/segment.js.map +1 -0
- package/dist/slack.cjs +368 -0
- package/dist/slack.cjs.map +1 -0
- package/dist/slack.d.cts +126 -0
- package/dist/slack.d.ts +126 -0
- package/dist/slack.js +366 -0
- package/dist/slack.js.map +1 -0
- package/dist/webhook.cjs +100 -0
- package/dist/webhook.cjs.map +1 -0
- package/dist/webhook.d.cts +53 -0
- package/dist/webhook.d.ts +53 -0
- package/dist/webhook.js +98 -0
- package/dist/webhook.js.map +1 -0
- package/examples/quickstart-custom-subscriber.ts +144 -0
- package/examples/subscriber-bigquery.ts +219 -0
- package/examples/subscriber-databricks.ts +280 -0
- package/examples/subscriber-kafka.ts +326 -0
- package/examples/subscriber-kinesis.ts +307 -0
- package/examples/subscriber-posthog.ts +421 -0
- package/examples/subscriber-pubsub.ts +336 -0
- package/examples/subscriber-snowflake.ts +232 -0
- package/package.json +141 -0
- package/src/amplitude.test.ts +231 -0
- package/src/amplitude.ts +148 -0
- package/src/event-subscriber-base.ts +325 -0
- package/src/factories.ts +197 -0
- package/src/index.ts +50 -0
- package/src/middleware.ts +489 -0
- package/src/mixpanel.test.ts +194 -0
- package/src/mixpanel.ts +134 -0
- package/src/mock-event-subscriber.ts +333 -0
- package/src/posthog.test.ts +629 -0
- package/src/posthog.ts +530 -0
- package/src/segment.test.ts +228 -0
- package/src/segment.ts +148 -0
- package/src/slack.ts +383 -0
- package/src/streaming-event-subscriber.ts +323 -0
- package/src/testing/index.ts +37 -0
- package/src/testing/mock-webhook-server.ts +242 -0
- package/src/testing/subscriber-test-harness.ts +365 -0
- package/src/webhook.test.ts +264 -0
- package/src/webhook.ts +158 -0
package/dist/posthog.cjs
ADDED
|
@@ -0,0 +1,4115 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var path = require('path');
|
|
4
|
+
var fs = require('fs');
|
|
5
|
+
var readline = require('readline');
|
|
6
|
+
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
12
|
+
var __export = (target, all) => {
|
|
13
|
+
for (var name in all)
|
|
14
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
15
|
+
};
|
|
16
|
+
function createModulerModifier() {
|
|
17
|
+
const getModuleFromFileName = createGetModuleFromFilename();
|
|
18
|
+
return async (frames) => {
|
|
19
|
+
for (const frame of frames) frame.module = getModuleFromFileName(frame.filename);
|
|
20
|
+
return frames;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? path.dirname(process.argv[1]) : process.cwd(), isWindows = "\\" === path.sep) {
|
|
24
|
+
const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
|
|
25
|
+
return (filename) => {
|
|
26
|
+
if (!filename) return;
|
|
27
|
+
const normalizedFilename = isWindows ? normalizeWindowsPath(filename) : filename;
|
|
28
|
+
let { dir, base: file, ext } = path.posix.parse(normalizedFilename);
|
|
29
|
+
if (".js" === ext || ".mjs" === ext || ".cjs" === ext) file = file.slice(0, -1 * ext.length);
|
|
30
|
+
const decodedFile = decodeURIComponent(file);
|
|
31
|
+
if (!dir) dir = ".";
|
|
32
|
+
const n = dir.lastIndexOf("/node_modules");
|
|
33
|
+
if (n > -1) return `${dir.slice(n + 14).replace(/\//g, ".")}:${decodedFile}`;
|
|
34
|
+
if (dir.startsWith(normalizedBase)) {
|
|
35
|
+
const moduleName = dir.slice(normalizedBase.length + 1).replace(/\//g, ".");
|
|
36
|
+
return moduleName ? `${moduleName}:${decodedFile}` : decodedFile;
|
|
37
|
+
}
|
|
38
|
+
return decodedFile;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function normalizeWindowsPath(path) {
|
|
42
|
+
return path.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
43
|
+
}
|
|
44
|
+
var init_module_node = __esm({
|
|
45
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs"() {
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
50
|
+
function getFlagDetailFromFlagAndPayload(key, value, payload) {
|
|
51
|
+
return {
|
|
52
|
+
key,
|
|
53
|
+
enabled: "string" == typeof value ? true : value,
|
|
54
|
+
variant: "string" == typeof value ? value : void 0,
|
|
55
|
+
reason: void 0,
|
|
56
|
+
metadata: {
|
|
57
|
+
id: void 0,
|
|
58
|
+
version: void 0,
|
|
59
|
+
payload: payload ? JSON.stringify(payload) : void 0,
|
|
60
|
+
description: void 0
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
var normalizeFlagsResponse, getFlagValuesFromFlags, getPayloadsFromFlags, getFeatureFlagValue, parsePayload;
|
|
65
|
+
var init_featureFlagUtils = __esm({
|
|
66
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/featureFlagUtils.mjs"() {
|
|
67
|
+
normalizeFlagsResponse = (flagsResponse) => {
|
|
68
|
+
if ("flags" in flagsResponse) {
|
|
69
|
+
const featureFlags = getFlagValuesFromFlags(flagsResponse.flags);
|
|
70
|
+
const featureFlagPayloads = getPayloadsFromFlags(flagsResponse.flags);
|
|
71
|
+
return {
|
|
72
|
+
...flagsResponse,
|
|
73
|
+
featureFlags,
|
|
74
|
+
featureFlagPayloads
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
{
|
|
78
|
+
const featureFlags = flagsResponse.featureFlags ?? {};
|
|
79
|
+
const featureFlagPayloads = Object.fromEntries(Object.entries(flagsResponse.featureFlagPayloads || {}).map(([k, v]) => [
|
|
80
|
+
k,
|
|
81
|
+
parsePayload(v)
|
|
82
|
+
]));
|
|
83
|
+
const flags = Object.fromEntries(Object.entries(featureFlags).map(([key, value]) => [
|
|
84
|
+
key,
|
|
85
|
+
getFlagDetailFromFlagAndPayload(key, value, featureFlagPayloads[key])
|
|
86
|
+
]));
|
|
87
|
+
return {
|
|
88
|
+
...flagsResponse,
|
|
89
|
+
featureFlags,
|
|
90
|
+
featureFlagPayloads,
|
|
91
|
+
flags
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
getFlagValuesFromFlags = (flags) => Object.fromEntries(Object.entries(flags ?? {}).map(([key, detail]) => [
|
|
96
|
+
key,
|
|
97
|
+
getFeatureFlagValue(detail)
|
|
98
|
+
]).filter(([, value]) => void 0 !== value));
|
|
99
|
+
getPayloadsFromFlags = (flags) => {
|
|
100
|
+
const safeFlags = flags ?? {};
|
|
101
|
+
return Object.fromEntries(Object.keys(safeFlags).filter((flag) => {
|
|
102
|
+
const details = safeFlags[flag];
|
|
103
|
+
return details.enabled && details.metadata && void 0 !== details.metadata.payload;
|
|
104
|
+
}).map((flag) => {
|
|
105
|
+
const payload = safeFlags[flag].metadata?.payload;
|
|
106
|
+
return [
|
|
107
|
+
flag,
|
|
108
|
+
payload ? parsePayload(payload) : void 0
|
|
109
|
+
];
|
|
110
|
+
}));
|
|
111
|
+
};
|
|
112
|
+
getFeatureFlagValue = (detail) => void 0 === detail ? void 0 : detail.variant ?? detail.enabled;
|
|
113
|
+
parsePayload = (response) => {
|
|
114
|
+
if ("string" != typeof response) return response;
|
|
115
|
+
try {
|
|
116
|
+
return JSON.parse(response);
|
|
117
|
+
} catch {
|
|
118
|
+
return response;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/vendor/uuidv7.mjs
|
|
125
|
+
var DIGITS, UUID, V7Generator, getDefaultRandom, defaultGenerator, uuidv7, uuidv7obj;
|
|
126
|
+
var init_uuidv7 = __esm({
|
|
127
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/vendor/uuidv7.mjs"() {
|
|
128
|
+
DIGITS = "0123456789abcdef";
|
|
129
|
+
UUID = class _UUID {
|
|
130
|
+
constructor(bytes) {
|
|
131
|
+
this.bytes = bytes;
|
|
132
|
+
}
|
|
133
|
+
static ofInner(bytes) {
|
|
134
|
+
if (16 === bytes.length) return new _UUID(bytes);
|
|
135
|
+
throw new TypeError("not 128-bit length");
|
|
136
|
+
}
|
|
137
|
+
static fromFieldsV7(unixTsMs, randA, randBHi, randBLo) {
|
|
138
|
+
if (!Number.isInteger(unixTsMs) || !Number.isInteger(randA) || !Number.isInteger(randBHi) || !Number.isInteger(randBLo) || unixTsMs < 0 || randA < 0 || randBHi < 0 || randBLo < 0 || unixTsMs > 281474976710655 || randA > 4095 || randBHi > 1073741823 || randBLo > 4294967295) throw new RangeError("invalid field value");
|
|
139
|
+
const bytes = new Uint8Array(16);
|
|
140
|
+
bytes[0] = unixTsMs / 2 ** 40;
|
|
141
|
+
bytes[1] = unixTsMs / 2 ** 32;
|
|
142
|
+
bytes[2] = unixTsMs / 2 ** 24;
|
|
143
|
+
bytes[3] = unixTsMs / 2 ** 16;
|
|
144
|
+
bytes[4] = unixTsMs / 256;
|
|
145
|
+
bytes[5] = unixTsMs;
|
|
146
|
+
bytes[6] = 112 | randA >>> 8;
|
|
147
|
+
bytes[7] = randA;
|
|
148
|
+
bytes[8] = 128 | randBHi >>> 24;
|
|
149
|
+
bytes[9] = randBHi >>> 16;
|
|
150
|
+
bytes[10] = randBHi >>> 8;
|
|
151
|
+
bytes[11] = randBHi;
|
|
152
|
+
bytes[12] = randBLo >>> 24;
|
|
153
|
+
bytes[13] = randBLo >>> 16;
|
|
154
|
+
bytes[14] = randBLo >>> 8;
|
|
155
|
+
bytes[15] = randBLo;
|
|
156
|
+
return new _UUID(bytes);
|
|
157
|
+
}
|
|
158
|
+
static parse(uuid) {
|
|
159
|
+
let hex;
|
|
160
|
+
switch (uuid.length) {
|
|
161
|
+
case 32:
|
|
162
|
+
hex = /^[0-9a-f]{32}$/i.exec(uuid)?.[0];
|
|
163
|
+
break;
|
|
164
|
+
case 36:
|
|
165
|
+
hex = /^([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})$/i.exec(uuid)?.slice(1, 6).join("");
|
|
166
|
+
break;
|
|
167
|
+
case 38:
|
|
168
|
+
hex = /^\{([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})\}$/i.exec(uuid)?.slice(1, 6).join("");
|
|
169
|
+
break;
|
|
170
|
+
case 45:
|
|
171
|
+
hex = /^urn:uuid:([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})$/i.exec(uuid)?.slice(1, 6).join("");
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
if (hex) {
|
|
175
|
+
const inner = new Uint8Array(16);
|
|
176
|
+
for (let i = 0; i < 16; i += 4) {
|
|
177
|
+
const n = parseInt(hex.substring(2 * i, 2 * i + 8), 16);
|
|
178
|
+
inner[i + 0] = n >>> 24;
|
|
179
|
+
inner[i + 1] = n >>> 16;
|
|
180
|
+
inner[i + 2] = n >>> 8;
|
|
181
|
+
inner[i + 3] = n;
|
|
182
|
+
}
|
|
183
|
+
return new _UUID(inner);
|
|
184
|
+
}
|
|
185
|
+
throw new SyntaxError("could not parse UUID string");
|
|
186
|
+
}
|
|
187
|
+
toString() {
|
|
188
|
+
let text = "";
|
|
189
|
+
for (let i = 0; i < this.bytes.length; i++) {
|
|
190
|
+
text += DIGITS.charAt(this.bytes[i] >>> 4);
|
|
191
|
+
text += DIGITS.charAt(15 & this.bytes[i]);
|
|
192
|
+
if (3 === i || 5 === i || 7 === i || 9 === i) text += "-";
|
|
193
|
+
}
|
|
194
|
+
return text;
|
|
195
|
+
}
|
|
196
|
+
toHex() {
|
|
197
|
+
let text = "";
|
|
198
|
+
for (let i = 0; i < this.bytes.length; i++) {
|
|
199
|
+
text += DIGITS.charAt(this.bytes[i] >>> 4);
|
|
200
|
+
text += DIGITS.charAt(15 & this.bytes[i]);
|
|
201
|
+
}
|
|
202
|
+
return text;
|
|
203
|
+
}
|
|
204
|
+
toJSON() {
|
|
205
|
+
return this.toString();
|
|
206
|
+
}
|
|
207
|
+
getVariant() {
|
|
208
|
+
const n = this.bytes[8] >>> 4;
|
|
209
|
+
if (n < 0) throw new Error("unreachable");
|
|
210
|
+
if (n <= 7) return this.bytes.every((e) => 0 === e) ? "NIL" : "VAR_0";
|
|
211
|
+
if (n <= 11) return "VAR_10";
|
|
212
|
+
if (n <= 13) return "VAR_110";
|
|
213
|
+
if (n <= 15) return this.bytes.every((e) => 255 === e) ? "MAX" : "VAR_RESERVED";
|
|
214
|
+
else throw new Error("unreachable");
|
|
215
|
+
}
|
|
216
|
+
getVersion() {
|
|
217
|
+
return "VAR_10" === this.getVariant() ? this.bytes[6] >>> 4 : void 0;
|
|
218
|
+
}
|
|
219
|
+
clone() {
|
|
220
|
+
return new _UUID(this.bytes.slice(0));
|
|
221
|
+
}
|
|
222
|
+
equals(other) {
|
|
223
|
+
return 0 === this.compareTo(other);
|
|
224
|
+
}
|
|
225
|
+
compareTo(other) {
|
|
226
|
+
for (let i = 0; i < 16; i++) {
|
|
227
|
+
const diff = this.bytes[i] - other.bytes[i];
|
|
228
|
+
if (0 !== diff) return Math.sign(diff);
|
|
229
|
+
}
|
|
230
|
+
return 0;
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
V7Generator = class {
|
|
234
|
+
constructor(randomNumberGenerator) {
|
|
235
|
+
this.timestamp = 0;
|
|
236
|
+
this.counter = 0;
|
|
237
|
+
this.random = randomNumberGenerator ?? getDefaultRandom();
|
|
238
|
+
}
|
|
239
|
+
generate() {
|
|
240
|
+
return this.generateOrResetCore(Date.now(), 1e4);
|
|
241
|
+
}
|
|
242
|
+
generateOrAbort() {
|
|
243
|
+
return this.generateOrAbortCore(Date.now(), 1e4);
|
|
244
|
+
}
|
|
245
|
+
generateOrResetCore(unixTsMs, rollbackAllowance) {
|
|
246
|
+
let value = this.generateOrAbortCore(unixTsMs, rollbackAllowance);
|
|
247
|
+
if (void 0 === value) {
|
|
248
|
+
this.timestamp = 0;
|
|
249
|
+
value = this.generateOrAbortCore(unixTsMs, rollbackAllowance);
|
|
250
|
+
}
|
|
251
|
+
return value;
|
|
252
|
+
}
|
|
253
|
+
generateOrAbortCore(unixTsMs, rollbackAllowance) {
|
|
254
|
+
const MAX_COUNTER = 4398046511103;
|
|
255
|
+
if (!Number.isInteger(unixTsMs) || unixTsMs < 1 || unixTsMs > 281474976710655) throw new RangeError("`unixTsMs` must be a 48-bit positive integer");
|
|
256
|
+
if (rollbackAllowance < 0 || rollbackAllowance > 281474976710655) throw new RangeError("`rollbackAllowance` out of reasonable range");
|
|
257
|
+
if (unixTsMs > this.timestamp) {
|
|
258
|
+
this.timestamp = unixTsMs;
|
|
259
|
+
this.resetCounter();
|
|
260
|
+
} else {
|
|
261
|
+
if (!(unixTsMs + rollbackAllowance >= this.timestamp)) return;
|
|
262
|
+
this.counter++;
|
|
263
|
+
if (this.counter > MAX_COUNTER) {
|
|
264
|
+
this.timestamp++;
|
|
265
|
+
this.resetCounter();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return UUID.fromFieldsV7(this.timestamp, Math.trunc(this.counter / 2 ** 30), this.counter & 2 ** 30 - 1, this.random.nextUint32());
|
|
269
|
+
}
|
|
270
|
+
resetCounter() {
|
|
271
|
+
this.counter = 1024 * this.random.nextUint32() + (1023 & this.random.nextUint32());
|
|
272
|
+
}
|
|
273
|
+
generateV4() {
|
|
274
|
+
const bytes = new Uint8Array(Uint32Array.of(this.random.nextUint32(), this.random.nextUint32(), this.random.nextUint32(), this.random.nextUint32()).buffer);
|
|
275
|
+
bytes[6] = 64 | bytes[6] >>> 4;
|
|
276
|
+
bytes[8] = 128 | bytes[8] >>> 2;
|
|
277
|
+
return UUID.ofInner(bytes);
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
getDefaultRandom = () => ({
|
|
281
|
+
nextUint32: () => 65536 * Math.trunc(65536 * Math.random()) + Math.trunc(65536 * Math.random())
|
|
282
|
+
});
|
|
283
|
+
uuidv7 = () => uuidv7obj().toString();
|
|
284
|
+
uuidv7obj = () => (defaultGenerator || (defaultGenerator = new V7Generator())).generate();
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/bot-detection.mjs
|
|
289
|
+
var DEFAULT_BLOCKED_UA_STRS, isBlockedUA;
|
|
290
|
+
var init_bot_detection = __esm({
|
|
291
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/bot-detection.mjs"() {
|
|
292
|
+
DEFAULT_BLOCKED_UA_STRS = [
|
|
293
|
+
"amazonbot",
|
|
294
|
+
"amazonproductbot",
|
|
295
|
+
"app.hypefactors.com",
|
|
296
|
+
"applebot",
|
|
297
|
+
"archive.org_bot",
|
|
298
|
+
"awariobot",
|
|
299
|
+
"backlinksextendedbot",
|
|
300
|
+
"baiduspider",
|
|
301
|
+
"bingbot",
|
|
302
|
+
"bingpreview",
|
|
303
|
+
"chrome-lighthouse",
|
|
304
|
+
"dataforseobot",
|
|
305
|
+
"deepscan",
|
|
306
|
+
"duckduckbot",
|
|
307
|
+
"facebookexternal",
|
|
308
|
+
"facebookcatalog",
|
|
309
|
+
"http://yandex.com/bots",
|
|
310
|
+
"hubspot",
|
|
311
|
+
"ia_archiver",
|
|
312
|
+
"leikibot",
|
|
313
|
+
"linkedinbot",
|
|
314
|
+
"meta-externalagent",
|
|
315
|
+
"mj12bot",
|
|
316
|
+
"msnbot",
|
|
317
|
+
"nessus",
|
|
318
|
+
"petalbot",
|
|
319
|
+
"pinterest",
|
|
320
|
+
"prerender",
|
|
321
|
+
"rogerbot",
|
|
322
|
+
"screaming frog",
|
|
323
|
+
"sebot-wa",
|
|
324
|
+
"sitebulb",
|
|
325
|
+
"slackbot",
|
|
326
|
+
"slurp",
|
|
327
|
+
"trendictionbot",
|
|
328
|
+
"turnitin",
|
|
329
|
+
"twitterbot",
|
|
330
|
+
"vercel-screenshot",
|
|
331
|
+
"vercelbot",
|
|
332
|
+
"yahoo! slurp",
|
|
333
|
+
"yandexbot",
|
|
334
|
+
"zoombot",
|
|
335
|
+
"bot.htm",
|
|
336
|
+
"bot.php",
|
|
337
|
+
"(bot;",
|
|
338
|
+
"bot/",
|
|
339
|
+
"crawler",
|
|
340
|
+
"ahrefsbot",
|
|
341
|
+
"ahrefssiteaudit",
|
|
342
|
+
"semrushbot",
|
|
343
|
+
"siteauditbot",
|
|
344
|
+
"splitsignalbot",
|
|
345
|
+
"gptbot",
|
|
346
|
+
"oai-searchbot",
|
|
347
|
+
"chatgpt-user",
|
|
348
|
+
"perplexitybot",
|
|
349
|
+
"better uptime bot",
|
|
350
|
+
"sentryuptimebot",
|
|
351
|
+
"uptimerobot",
|
|
352
|
+
"headlesschrome",
|
|
353
|
+
"cypress",
|
|
354
|
+
"google-hoteladsverifier",
|
|
355
|
+
"adsbot-google",
|
|
356
|
+
"apis-google",
|
|
357
|
+
"duplexweb-google",
|
|
358
|
+
"feedfetcher-google",
|
|
359
|
+
"google favicon",
|
|
360
|
+
"google web preview",
|
|
361
|
+
"google-read-aloud",
|
|
362
|
+
"googlebot",
|
|
363
|
+
"googleother",
|
|
364
|
+
"google-cloudvertexbot",
|
|
365
|
+
"googleweblight",
|
|
366
|
+
"mediapartners-google",
|
|
367
|
+
"storebot-google",
|
|
368
|
+
"google-inspectiontool",
|
|
369
|
+
"bytespider"
|
|
370
|
+
];
|
|
371
|
+
isBlockedUA = function(ua, customBlockedUserAgents = []) {
|
|
372
|
+
if (!ua) return false;
|
|
373
|
+
const uaLower = ua.toLowerCase();
|
|
374
|
+
return DEFAULT_BLOCKED_UA_STRS.concat(customBlockedUserAgents).some((blockedUA) => {
|
|
375
|
+
const blockedUaLower = blockedUA.toLowerCase();
|
|
376
|
+
return -1 !== uaLower.indexOf(blockedUaLower);
|
|
377
|
+
});
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/types.mjs
|
|
383
|
+
var types_PostHogPersistedProperty;
|
|
384
|
+
var init_types = __esm({
|
|
385
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/types.mjs"() {
|
|
386
|
+
types_PostHogPersistedProperty = /* @__PURE__ */ (function(PostHogPersistedProperty) {
|
|
387
|
+
PostHogPersistedProperty["AnonymousId"] = "anonymous_id";
|
|
388
|
+
PostHogPersistedProperty["DistinctId"] = "distinct_id";
|
|
389
|
+
PostHogPersistedProperty["Props"] = "props";
|
|
390
|
+
PostHogPersistedProperty["FeatureFlagDetails"] = "feature_flag_details";
|
|
391
|
+
PostHogPersistedProperty["FeatureFlags"] = "feature_flags";
|
|
392
|
+
PostHogPersistedProperty["FeatureFlagPayloads"] = "feature_flag_payloads";
|
|
393
|
+
PostHogPersistedProperty["BootstrapFeatureFlagDetails"] = "bootstrap_feature_flag_details";
|
|
394
|
+
PostHogPersistedProperty["BootstrapFeatureFlags"] = "bootstrap_feature_flags";
|
|
395
|
+
PostHogPersistedProperty["BootstrapFeatureFlagPayloads"] = "bootstrap_feature_flag_payloads";
|
|
396
|
+
PostHogPersistedProperty["OverrideFeatureFlags"] = "override_feature_flags";
|
|
397
|
+
PostHogPersistedProperty["Queue"] = "queue";
|
|
398
|
+
PostHogPersistedProperty["OptedOut"] = "opted_out";
|
|
399
|
+
PostHogPersistedProperty["SessionId"] = "session_id";
|
|
400
|
+
PostHogPersistedProperty["SessionStartTimestamp"] = "session_start_timestamp";
|
|
401
|
+
PostHogPersistedProperty["SessionLastTimestamp"] = "session_timestamp";
|
|
402
|
+
PostHogPersistedProperty["PersonProperties"] = "person_properties";
|
|
403
|
+
PostHogPersistedProperty["GroupProperties"] = "group_properties";
|
|
404
|
+
PostHogPersistedProperty["InstalledAppBuild"] = "installed_app_build";
|
|
405
|
+
PostHogPersistedProperty["InstalledAppVersion"] = "installed_app_version";
|
|
406
|
+
PostHogPersistedProperty["SessionReplay"] = "session_replay";
|
|
407
|
+
PostHogPersistedProperty["SurveyLastSeenDate"] = "survey_last_seen_date";
|
|
408
|
+
PostHogPersistedProperty["SurveysSeen"] = "surveys_seen";
|
|
409
|
+
PostHogPersistedProperty["Surveys"] = "surveys";
|
|
410
|
+
PostHogPersistedProperty["RemoteConfig"] = "remote_config";
|
|
411
|
+
PostHogPersistedProperty["FlagsEndpointWasHit"] = "flags_endpoint_was_hit";
|
|
412
|
+
return PostHogPersistedProperty;
|
|
413
|
+
})({});
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/string-utils.mjs
|
|
418
|
+
var init_string_utils = __esm({
|
|
419
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/string-utils.mjs"() {
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/type-utils.mjs
|
|
424
|
+
function isInstanceOf(candidate, base) {
|
|
425
|
+
try {
|
|
426
|
+
return candidate instanceof base;
|
|
427
|
+
} catch {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
function isPrimitive(value) {
|
|
432
|
+
return null === value || "object" != typeof value;
|
|
433
|
+
}
|
|
434
|
+
function isBuiltin(candidate, className) {
|
|
435
|
+
return Object.prototype.toString.call(candidate) === `[object ${className}]`;
|
|
436
|
+
}
|
|
437
|
+
function isErrorEvent(event) {
|
|
438
|
+
return isBuiltin(event, "ErrorEvent");
|
|
439
|
+
}
|
|
440
|
+
function isEvent(candidate) {
|
|
441
|
+
return !isUndefined(Event) && isInstanceOf(candidate, Event);
|
|
442
|
+
}
|
|
443
|
+
function isPlainObject(candidate) {
|
|
444
|
+
return isBuiltin(candidate, "Object");
|
|
445
|
+
}
|
|
446
|
+
var nativeIsArray, ObjProto, type_utils_toString, isArray, isUndefined, isString, isEmptyString, isNumber, isPlainError;
|
|
447
|
+
var init_type_utils = __esm({
|
|
448
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/type-utils.mjs"() {
|
|
449
|
+
init_types();
|
|
450
|
+
init_string_utils();
|
|
451
|
+
nativeIsArray = Array.isArray;
|
|
452
|
+
ObjProto = Object.prototype;
|
|
453
|
+
ObjProto.hasOwnProperty;
|
|
454
|
+
type_utils_toString = ObjProto.toString;
|
|
455
|
+
isArray = nativeIsArray || function(obj) {
|
|
456
|
+
return "[object Array]" === type_utils_toString.call(obj);
|
|
457
|
+
};
|
|
458
|
+
isUndefined = (x) => void 0 === x;
|
|
459
|
+
isString = (x) => "[object String]" == type_utils_toString.call(x);
|
|
460
|
+
isEmptyString = (x) => isString(x) && 0 === x.trim().length;
|
|
461
|
+
isNumber = (x) => "[object Number]" == type_utils_toString.call(x);
|
|
462
|
+
isPlainError = (x) => x instanceof Error;
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/number-utils.mjs
|
|
467
|
+
function clampToRange(value, min, max, logger, fallbackValue) {
|
|
468
|
+
if (min > max) {
|
|
469
|
+
logger.warn("min cannot be greater than max.");
|
|
470
|
+
min = max;
|
|
471
|
+
}
|
|
472
|
+
if (isNumber(value)) if (value > max) {
|
|
473
|
+
logger.warn(" cannot be greater than max: " + max + ". Using max value instead.");
|
|
474
|
+
return max;
|
|
475
|
+
} else {
|
|
476
|
+
if (!(value < min)) return value;
|
|
477
|
+
logger.warn(" cannot be less than min: " + min + ". Using min value instead.");
|
|
478
|
+
return min;
|
|
479
|
+
}
|
|
480
|
+
logger.warn(" must be a number. using max or fallback. max: " + max + ", fallback: " + fallbackValue);
|
|
481
|
+
return clampToRange(max, min, max, logger);
|
|
482
|
+
}
|
|
483
|
+
var init_number_utils = __esm({
|
|
484
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/number-utils.mjs"() {
|
|
485
|
+
init_type_utils();
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/bucketed-rate-limiter.mjs
|
|
490
|
+
var ONE_DAY_IN_MS, BucketedRateLimiter;
|
|
491
|
+
var init_bucketed_rate_limiter = __esm({
|
|
492
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/bucketed-rate-limiter.mjs"() {
|
|
493
|
+
init_number_utils();
|
|
494
|
+
ONE_DAY_IN_MS = 864e5;
|
|
495
|
+
BucketedRateLimiter = class {
|
|
496
|
+
constructor(options) {
|
|
497
|
+
this._buckets = {};
|
|
498
|
+
this._onBucketRateLimited = options._onBucketRateLimited;
|
|
499
|
+
this._bucketSize = clampToRange(options.bucketSize, 0, 100, options._logger);
|
|
500
|
+
this._refillRate = clampToRange(options.refillRate, 0, this._bucketSize, options._logger);
|
|
501
|
+
this._refillInterval = clampToRange(options.refillInterval, 0, ONE_DAY_IN_MS, options._logger);
|
|
502
|
+
}
|
|
503
|
+
_applyRefill(bucket, now) {
|
|
504
|
+
const elapsedMs = now - bucket.lastAccess;
|
|
505
|
+
const refillIntervals = Math.floor(elapsedMs / this._refillInterval);
|
|
506
|
+
if (refillIntervals > 0) {
|
|
507
|
+
const tokensToAdd = refillIntervals * this._refillRate;
|
|
508
|
+
bucket.tokens = Math.min(bucket.tokens + tokensToAdd, this._bucketSize);
|
|
509
|
+
bucket.lastAccess = bucket.lastAccess + refillIntervals * this._refillInterval;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
consumeRateLimit(key) {
|
|
513
|
+
const now = Date.now();
|
|
514
|
+
const keyStr = String(key);
|
|
515
|
+
let bucket = this._buckets[keyStr];
|
|
516
|
+
if (bucket) this._applyRefill(bucket, now);
|
|
517
|
+
else {
|
|
518
|
+
bucket = {
|
|
519
|
+
tokens: this._bucketSize,
|
|
520
|
+
lastAccess: now
|
|
521
|
+
};
|
|
522
|
+
this._buckets[keyStr] = bucket;
|
|
523
|
+
}
|
|
524
|
+
if (0 === bucket.tokens) return true;
|
|
525
|
+
bucket.tokens--;
|
|
526
|
+
if (0 === bucket.tokens) this._onBucketRateLimited?.(key);
|
|
527
|
+
return 0 === bucket.tokens;
|
|
528
|
+
}
|
|
529
|
+
stop() {
|
|
530
|
+
this._buckets = {};
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/promise-queue.mjs
|
|
537
|
+
var PromiseQueue;
|
|
538
|
+
var init_promise_queue = __esm({
|
|
539
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/promise-queue.mjs"() {
|
|
540
|
+
init_uuidv7();
|
|
541
|
+
PromiseQueue = class {
|
|
542
|
+
add(promise) {
|
|
543
|
+
const promiseUUID = uuidv7();
|
|
544
|
+
this.promiseByIds[promiseUUID] = promise;
|
|
545
|
+
promise.catch(() => {
|
|
546
|
+
}).finally(() => {
|
|
547
|
+
delete this.promiseByIds[promiseUUID];
|
|
548
|
+
});
|
|
549
|
+
return promise;
|
|
550
|
+
}
|
|
551
|
+
async join() {
|
|
552
|
+
let promises = Object.values(this.promiseByIds);
|
|
553
|
+
let length = promises.length;
|
|
554
|
+
while (length > 0) {
|
|
555
|
+
await Promise.all(promises);
|
|
556
|
+
promises = Object.values(this.promiseByIds);
|
|
557
|
+
length = promises.length;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
get length() {
|
|
561
|
+
return Object.keys(this.promiseByIds).length;
|
|
562
|
+
}
|
|
563
|
+
constructor() {
|
|
564
|
+
this.promiseByIds = {};
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/logger.mjs
|
|
571
|
+
function createConsole(consoleLike = console) {
|
|
572
|
+
const lockedMethods = {
|
|
573
|
+
log: consoleLike.log.bind(consoleLike),
|
|
574
|
+
warn: consoleLike.warn.bind(consoleLike),
|
|
575
|
+
error: consoleLike.error.bind(consoleLike),
|
|
576
|
+
debug: consoleLike.debug.bind(consoleLike)
|
|
577
|
+
};
|
|
578
|
+
return lockedMethods;
|
|
579
|
+
}
|
|
580
|
+
function createLogger(prefix, maybeCall = passThrough) {
|
|
581
|
+
return _createLogger(prefix, maybeCall, createConsole());
|
|
582
|
+
}
|
|
583
|
+
var _createLogger, passThrough;
|
|
584
|
+
var init_logger = __esm({
|
|
585
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/logger.mjs"() {
|
|
586
|
+
_createLogger = (prefix, maybeCall, consoleLike) => {
|
|
587
|
+
function _log(level, ...args) {
|
|
588
|
+
maybeCall(() => {
|
|
589
|
+
const consoleMethod = consoleLike[level];
|
|
590
|
+
consoleMethod(prefix, ...args);
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
const logger = {
|
|
594
|
+
info: (...args) => {
|
|
595
|
+
_log("log", ...args);
|
|
596
|
+
},
|
|
597
|
+
warn: (...args) => {
|
|
598
|
+
_log("warn", ...args);
|
|
599
|
+
},
|
|
600
|
+
error: (...args) => {
|
|
601
|
+
_log("error", ...args);
|
|
602
|
+
},
|
|
603
|
+
critical: (...args) => {
|
|
604
|
+
consoleLike["error"](prefix, ...args);
|
|
605
|
+
},
|
|
606
|
+
createLogger: (additionalPrefix) => _createLogger(`${prefix} ${additionalPrefix}`, maybeCall, consoleLike)
|
|
607
|
+
};
|
|
608
|
+
return logger;
|
|
609
|
+
};
|
|
610
|
+
passThrough = (fn) => fn();
|
|
611
|
+
}
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/index.mjs
|
|
615
|
+
function assert(truthyValue, message) {
|
|
616
|
+
if (!truthyValue || "string" != typeof truthyValue || isEmpty(truthyValue)) throw new Error(message);
|
|
617
|
+
}
|
|
618
|
+
function isEmpty(truthyValue) {
|
|
619
|
+
if (0 === truthyValue.trim().length) return true;
|
|
620
|
+
return false;
|
|
621
|
+
}
|
|
622
|
+
function removeTrailingSlash(url) {
|
|
623
|
+
return url?.replace(/\/+$/, "");
|
|
624
|
+
}
|
|
625
|
+
async function retriable(fn, props) {
|
|
626
|
+
let lastError = null;
|
|
627
|
+
for (let i = 0; i < props.retryCount + 1; i++) {
|
|
628
|
+
if (i > 0) await new Promise((r) => setTimeout(r, props.retryDelay));
|
|
629
|
+
try {
|
|
630
|
+
const res = await fn();
|
|
631
|
+
return res;
|
|
632
|
+
} catch (e) {
|
|
633
|
+
lastError = e;
|
|
634
|
+
if (!props.retryCheck(e)) throw e;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
throw lastError;
|
|
638
|
+
}
|
|
639
|
+
function currentISOTime() {
|
|
640
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
641
|
+
}
|
|
642
|
+
function safeSetTimeout(fn, timeout) {
|
|
643
|
+
const t = setTimeout(fn, timeout);
|
|
644
|
+
t?.unref && t?.unref();
|
|
645
|
+
return t;
|
|
646
|
+
}
|
|
647
|
+
function allSettled(promises) {
|
|
648
|
+
return Promise.all(promises.map((p) => (p ?? Promise.resolve()).then((value) => ({
|
|
649
|
+
status: "fulfilled",
|
|
650
|
+
value
|
|
651
|
+
}), (reason) => ({
|
|
652
|
+
status: "rejected",
|
|
653
|
+
reason
|
|
654
|
+
}))));
|
|
655
|
+
}
|
|
656
|
+
var STRING_FORMAT, isError;
|
|
657
|
+
var init_utils = __esm({
|
|
658
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/utils/index.mjs"() {
|
|
659
|
+
init_bot_detection();
|
|
660
|
+
init_bucketed_rate_limiter();
|
|
661
|
+
init_number_utils();
|
|
662
|
+
init_string_utils();
|
|
663
|
+
init_type_utils();
|
|
664
|
+
init_promise_queue();
|
|
665
|
+
init_logger();
|
|
666
|
+
STRING_FORMAT = "utf8";
|
|
667
|
+
isError = (x) => x instanceof Error;
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/eventemitter.mjs
|
|
672
|
+
var SimpleEventEmitter;
|
|
673
|
+
var init_eventemitter = __esm({
|
|
674
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/eventemitter.mjs"() {
|
|
675
|
+
SimpleEventEmitter = class {
|
|
676
|
+
constructor() {
|
|
677
|
+
this.events = {};
|
|
678
|
+
this.events = {};
|
|
679
|
+
}
|
|
680
|
+
on(event, listener) {
|
|
681
|
+
if (!this.events[event]) this.events[event] = [];
|
|
682
|
+
this.events[event].push(listener);
|
|
683
|
+
return () => {
|
|
684
|
+
this.events[event] = this.events[event].filter((x) => x !== listener);
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
emit(event, payload) {
|
|
688
|
+
for (const listener of this.events[event] || []) listener(payload);
|
|
689
|
+
for (const listener of this.events["*"] || []) listener(event, payload);
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/gzip.mjs
|
|
696
|
+
function isGzipSupported() {
|
|
697
|
+
return "CompressionStream" in globalThis;
|
|
698
|
+
}
|
|
699
|
+
async function gzipCompress(input, isDebug = true) {
|
|
700
|
+
try {
|
|
701
|
+
const dataStream = new Blob([
|
|
702
|
+
input
|
|
703
|
+
], {
|
|
704
|
+
type: "text/plain"
|
|
705
|
+
}).stream();
|
|
706
|
+
const compressedStream = dataStream.pipeThrough(new CompressionStream("gzip"));
|
|
707
|
+
return await new Response(compressedStream).blob();
|
|
708
|
+
} catch (error) {
|
|
709
|
+
if (isDebug) console.error("Failed to gzip compress data", error);
|
|
710
|
+
return null;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
var init_gzip = __esm({
|
|
714
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/gzip.mjs"() {
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/posthog-core-stateless.mjs
|
|
719
|
+
async function logFlushError(err) {
|
|
720
|
+
if (err instanceof PostHogFetchHttpError) {
|
|
721
|
+
let text = "";
|
|
722
|
+
try {
|
|
723
|
+
text = await err.text;
|
|
724
|
+
} catch {
|
|
725
|
+
}
|
|
726
|
+
console.error(`Error while flushing PostHog: message=${err.message}, response body=${text}`, err);
|
|
727
|
+
} else console.error("Error while flushing PostHog", err);
|
|
728
|
+
return Promise.resolve();
|
|
729
|
+
}
|
|
730
|
+
function isPostHogFetchError(err) {
|
|
731
|
+
return "object" == typeof err && (err instanceof PostHogFetchHttpError || err instanceof PostHogFetchNetworkError);
|
|
732
|
+
}
|
|
733
|
+
function isPostHogFetchContentTooLargeError(err) {
|
|
734
|
+
return "object" == typeof err && err instanceof PostHogFetchHttpError && 413 === err.status;
|
|
735
|
+
}
|
|
736
|
+
var PostHogFetchHttpError, PostHogFetchNetworkError, PostHogCoreStateless;
|
|
737
|
+
var init_posthog_core_stateless = __esm({
|
|
738
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/posthog-core-stateless.mjs"() {
|
|
739
|
+
init_eventemitter();
|
|
740
|
+
init_featureFlagUtils();
|
|
741
|
+
init_gzip();
|
|
742
|
+
init_types();
|
|
743
|
+
init_utils();
|
|
744
|
+
init_uuidv7();
|
|
745
|
+
PostHogFetchHttpError = class extends Error {
|
|
746
|
+
constructor(response, reqByteLength) {
|
|
747
|
+
super("HTTP error while fetching PostHog: status=" + response.status + ", reqByteLength=" + reqByteLength), this.response = response, this.reqByteLength = reqByteLength, this.name = "PostHogFetchHttpError";
|
|
748
|
+
}
|
|
749
|
+
get status() {
|
|
750
|
+
return this.response.status;
|
|
751
|
+
}
|
|
752
|
+
get text() {
|
|
753
|
+
return this.response.text();
|
|
754
|
+
}
|
|
755
|
+
get json() {
|
|
756
|
+
return this.response.json();
|
|
757
|
+
}
|
|
758
|
+
};
|
|
759
|
+
PostHogFetchNetworkError = class extends Error {
|
|
760
|
+
constructor(error) {
|
|
761
|
+
super("Network error while fetching PostHog", error instanceof Error ? {
|
|
762
|
+
cause: error
|
|
763
|
+
} : {}), this.error = error, this.name = "PostHogFetchNetworkError";
|
|
764
|
+
}
|
|
765
|
+
};
|
|
766
|
+
PostHogCoreStateless = class {
|
|
767
|
+
constructor(apiKey, options = {}) {
|
|
768
|
+
this.flushPromise = null;
|
|
769
|
+
this.shutdownPromise = null;
|
|
770
|
+
this.promiseQueue = new PromiseQueue();
|
|
771
|
+
this._events = new SimpleEventEmitter();
|
|
772
|
+
this._isInitialized = false;
|
|
773
|
+
assert(apiKey, "You must pass your PostHog project's api key.");
|
|
774
|
+
this.apiKey = apiKey;
|
|
775
|
+
this.host = removeTrailingSlash(options.host || "https://us.i.posthog.com");
|
|
776
|
+
this.flushAt = options.flushAt ? Math.max(options.flushAt, 1) : 20;
|
|
777
|
+
this.maxBatchSize = Math.max(this.flushAt, options.maxBatchSize ?? 100);
|
|
778
|
+
this.maxQueueSize = Math.max(this.flushAt, options.maxQueueSize ?? 1e3);
|
|
779
|
+
this.flushInterval = options.flushInterval ?? 1e4;
|
|
780
|
+
this.preloadFeatureFlags = options.preloadFeatureFlags ?? true;
|
|
781
|
+
this.defaultOptIn = options.defaultOptIn ?? true;
|
|
782
|
+
this.disableSurveys = options.disableSurveys ?? false;
|
|
783
|
+
this._retryOptions = {
|
|
784
|
+
retryCount: options.fetchRetryCount ?? 3,
|
|
785
|
+
retryDelay: options.fetchRetryDelay ?? 3e3,
|
|
786
|
+
retryCheck: isPostHogFetchError
|
|
787
|
+
};
|
|
788
|
+
this.requestTimeout = options.requestTimeout ?? 1e4;
|
|
789
|
+
this.featureFlagsRequestTimeoutMs = options.featureFlagsRequestTimeoutMs ?? 3e3;
|
|
790
|
+
this.remoteConfigRequestTimeoutMs = options.remoteConfigRequestTimeoutMs ?? 3e3;
|
|
791
|
+
this.disableGeoip = options.disableGeoip ?? true;
|
|
792
|
+
this.disabled = options.disabled ?? false;
|
|
793
|
+
this.historicalMigration = options?.historicalMigration ?? false;
|
|
794
|
+
this.evaluationEnvironments = options?.evaluationEnvironments;
|
|
795
|
+
this._initPromise = Promise.resolve();
|
|
796
|
+
this._isInitialized = true;
|
|
797
|
+
this._logger = createLogger("[PostHog]", this.logMsgIfDebug.bind(this));
|
|
798
|
+
this.disableCompression = !isGzipSupported() || (options?.disableCompression ?? false);
|
|
799
|
+
}
|
|
800
|
+
logMsgIfDebug(fn) {
|
|
801
|
+
if (this.isDebug) fn();
|
|
802
|
+
}
|
|
803
|
+
wrap(fn) {
|
|
804
|
+
if (this.disabled) return void this._logger.warn("The client is disabled");
|
|
805
|
+
if (this._isInitialized) return fn();
|
|
806
|
+
this._initPromise.then(() => fn());
|
|
807
|
+
}
|
|
808
|
+
getCommonEventProperties() {
|
|
809
|
+
return {
|
|
810
|
+
$lib: this.getLibraryId(),
|
|
811
|
+
$lib_version: this.getLibraryVersion()
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
get optedOut() {
|
|
815
|
+
return this.getPersistedProperty(types_PostHogPersistedProperty.OptedOut) ?? !this.defaultOptIn;
|
|
816
|
+
}
|
|
817
|
+
async optIn() {
|
|
818
|
+
this.wrap(() => {
|
|
819
|
+
this.setPersistedProperty(types_PostHogPersistedProperty.OptedOut, false);
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
async optOut() {
|
|
823
|
+
this.wrap(() => {
|
|
824
|
+
this.setPersistedProperty(types_PostHogPersistedProperty.OptedOut, true);
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
on(event, cb) {
|
|
828
|
+
return this._events.on(event, cb);
|
|
829
|
+
}
|
|
830
|
+
debug(enabled = true) {
|
|
831
|
+
this.removeDebugCallback?.();
|
|
832
|
+
if (enabled) {
|
|
833
|
+
const removeDebugCallback = this.on("*", (event, payload) => this._logger.info(event, payload));
|
|
834
|
+
this.removeDebugCallback = () => {
|
|
835
|
+
removeDebugCallback();
|
|
836
|
+
this.removeDebugCallback = void 0;
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
get isDebug() {
|
|
841
|
+
return !!this.removeDebugCallback;
|
|
842
|
+
}
|
|
843
|
+
get isDisabled() {
|
|
844
|
+
return this.disabled;
|
|
845
|
+
}
|
|
846
|
+
buildPayload(payload) {
|
|
847
|
+
return {
|
|
848
|
+
distinct_id: payload.distinct_id,
|
|
849
|
+
event: payload.event,
|
|
850
|
+
properties: {
|
|
851
|
+
...payload.properties || {},
|
|
852
|
+
...this.getCommonEventProperties()
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
addPendingPromise(promise) {
|
|
857
|
+
return this.promiseQueue.add(promise);
|
|
858
|
+
}
|
|
859
|
+
identifyStateless(distinctId, properties, options) {
|
|
860
|
+
this.wrap(() => {
|
|
861
|
+
const payload = {
|
|
862
|
+
...this.buildPayload({
|
|
863
|
+
distinct_id: distinctId,
|
|
864
|
+
event: "$identify",
|
|
865
|
+
properties
|
|
866
|
+
})
|
|
867
|
+
};
|
|
868
|
+
this.enqueue("identify", payload, options);
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
async identifyStatelessImmediate(distinctId, properties, options) {
|
|
872
|
+
const payload = {
|
|
873
|
+
...this.buildPayload({
|
|
874
|
+
distinct_id: distinctId,
|
|
875
|
+
event: "$identify",
|
|
876
|
+
properties
|
|
877
|
+
})
|
|
878
|
+
};
|
|
879
|
+
await this.sendImmediate("identify", payload, options);
|
|
880
|
+
}
|
|
881
|
+
captureStateless(distinctId, event, properties, options) {
|
|
882
|
+
this.wrap(() => {
|
|
883
|
+
const payload = this.buildPayload({
|
|
884
|
+
distinct_id: distinctId,
|
|
885
|
+
event,
|
|
886
|
+
properties
|
|
887
|
+
});
|
|
888
|
+
this.enqueue("capture", payload, options);
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
async captureStatelessImmediate(distinctId, event, properties, options) {
|
|
892
|
+
const payload = this.buildPayload({
|
|
893
|
+
distinct_id: distinctId,
|
|
894
|
+
event,
|
|
895
|
+
properties
|
|
896
|
+
});
|
|
897
|
+
await this.sendImmediate("capture", payload, options);
|
|
898
|
+
}
|
|
899
|
+
aliasStateless(alias, distinctId, properties, options) {
|
|
900
|
+
this.wrap(() => {
|
|
901
|
+
const payload = this.buildPayload({
|
|
902
|
+
event: "$create_alias",
|
|
903
|
+
distinct_id: distinctId,
|
|
904
|
+
properties: {
|
|
905
|
+
...properties || {},
|
|
906
|
+
distinct_id: distinctId,
|
|
907
|
+
alias
|
|
908
|
+
}
|
|
909
|
+
});
|
|
910
|
+
this.enqueue("alias", payload, options);
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
async aliasStatelessImmediate(alias, distinctId, properties, options) {
|
|
914
|
+
const payload = this.buildPayload({
|
|
915
|
+
event: "$create_alias",
|
|
916
|
+
distinct_id: distinctId,
|
|
917
|
+
properties: {
|
|
918
|
+
...properties || {},
|
|
919
|
+
distinct_id: distinctId,
|
|
920
|
+
alias
|
|
921
|
+
}
|
|
922
|
+
});
|
|
923
|
+
await this.sendImmediate("alias", payload, options);
|
|
924
|
+
}
|
|
925
|
+
groupIdentifyStateless(groupType, groupKey, groupProperties, options, distinctId, eventProperties) {
|
|
926
|
+
this.wrap(() => {
|
|
927
|
+
const payload = this.buildPayload({
|
|
928
|
+
distinct_id: distinctId || `$${groupType}_${groupKey}`,
|
|
929
|
+
event: "$groupidentify",
|
|
930
|
+
properties: {
|
|
931
|
+
$group_type: groupType,
|
|
932
|
+
$group_key: groupKey,
|
|
933
|
+
$group_set: groupProperties || {},
|
|
934
|
+
...eventProperties || {}
|
|
935
|
+
}
|
|
936
|
+
});
|
|
937
|
+
this.enqueue("capture", payload, options);
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
async getRemoteConfig() {
|
|
941
|
+
await this._initPromise;
|
|
942
|
+
let host = this.host;
|
|
943
|
+
if ("https://us.i.posthog.com" === host) host = "https://us-assets.i.posthog.com";
|
|
944
|
+
else if ("https://eu.i.posthog.com" === host) host = "https://eu-assets.i.posthog.com";
|
|
945
|
+
const url = `${host}/array/${this.apiKey}/config`;
|
|
946
|
+
const fetchOptions = {
|
|
947
|
+
method: "GET",
|
|
948
|
+
headers: {
|
|
949
|
+
...this.getCustomHeaders(),
|
|
950
|
+
"Content-Type": "application/json"
|
|
951
|
+
}
|
|
952
|
+
};
|
|
953
|
+
return this.fetchWithRetry(url, fetchOptions, {
|
|
954
|
+
retryCount: 0
|
|
955
|
+
}, this.remoteConfigRequestTimeoutMs).then((response) => response.json()).catch((error) => {
|
|
956
|
+
this._logger.error("Remote config could not be loaded", error);
|
|
957
|
+
this._events.emit("error", error);
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
async getFlags(distinctId, groups = {}, personProperties = {}, groupProperties = {}, extraPayload = {}, fetchConfig = true) {
|
|
961
|
+
await this._initPromise;
|
|
962
|
+
const configParam = fetchConfig ? "&config=true" : "";
|
|
963
|
+
const url = `${this.host}/flags/?v=2${configParam}`;
|
|
964
|
+
const requestData = {
|
|
965
|
+
token: this.apiKey,
|
|
966
|
+
distinct_id: distinctId,
|
|
967
|
+
groups,
|
|
968
|
+
person_properties: personProperties,
|
|
969
|
+
group_properties: groupProperties,
|
|
970
|
+
...extraPayload
|
|
971
|
+
};
|
|
972
|
+
if (this.evaluationEnvironments && this.evaluationEnvironments.length > 0) requestData.evaluation_environments = this.evaluationEnvironments;
|
|
973
|
+
const fetchOptions = {
|
|
974
|
+
method: "POST",
|
|
975
|
+
headers: {
|
|
976
|
+
...this.getCustomHeaders(),
|
|
977
|
+
"Content-Type": "application/json"
|
|
978
|
+
},
|
|
979
|
+
body: JSON.stringify(requestData)
|
|
980
|
+
};
|
|
981
|
+
this._logger.info("Flags URL", url);
|
|
982
|
+
return this.fetchWithRetry(url, fetchOptions, {
|
|
983
|
+
retryCount: 0
|
|
984
|
+
}, this.featureFlagsRequestTimeoutMs).then((response) => response.json()).then((response) => normalizeFlagsResponse(response)).catch((error) => {
|
|
985
|
+
this._events.emit("error", error);
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
async getFeatureFlagStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
989
|
+
await this._initPromise;
|
|
990
|
+
const flagDetailResponse = await this.getFeatureFlagDetailStateless(key, distinctId, groups, personProperties, groupProperties, disableGeoip);
|
|
991
|
+
if (void 0 === flagDetailResponse) return {
|
|
992
|
+
response: void 0,
|
|
993
|
+
requestId: void 0
|
|
994
|
+
};
|
|
995
|
+
let response = getFeatureFlagValue(flagDetailResponse.response);
|
|
996
|
+
if (void 0 === response) response = false;
|
|
997
|
+
return {
|
|
998
|
+
response,
|
|
999
|
+
requestId: flagDetailResponse.requestId
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
async getFeatureFlagDetailStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1003
|
+
await this._initPromise;
|
|
1004
|
+
const flagsResponse = await this.getFeatureFlagDetailsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, [
|
|
1005
|
+
key
|
|
1006
|
+
]);
|
|
1007
|
+
if (void 0 === flagsResponse) return;
|
|
1008
|
+
const featureFlags = flagsResponse.flags;
|
|
1009
|
+
const flagDetail = featureFlags[key];
|
|
1010
|
+
return {
|
|
1011
|
+
response: flagDetail,
|
|
1012
|
+
requestId: flagsResponse.requestId
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
async getFeatureFlagPayloadStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1016
|
+
await this._initPromise;
|
|
1017
|
+
const payloads = await this.getFeatureFlagPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, [
|
|
1018
|
+
key
|
|
1019
|
+
]);
|
|
1020
|
+
if (!payloads) return;
|
|
1021
|
+
const response = payloads[key];
|
|
1022
|
+
if (void 0 === response) return null;
|
|
1023
|
+
return response;
|
|
1024
|
+
}
|
|
1025
|
+
async getFeatureFlagPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
|
|
1026
|
+
await this._initPromise;
|
|
1027
|
+
const payloads = (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate)).payloads;
|
|
1028
|
+
return payloads;
|
|
1029
|
+
}
|
|
1030
|
+
async getFeatureFlagsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
|
|
1031
|
+
await this._initPromise;
|
|
1032
|
+
return await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate);
|
|
1033
|
+
}
|
|
1034
|
+
async getFeatureFlagsAndPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
|
|
1035
|
+
await this._initPromise;
|
|
1036
|
+
const featureFlagDetails = await this.getFeatureFlagDetailsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate);
|
|
1037
|
+
if (!featureFlagDetails) return {
|
|
1038
|
+
flags: void 0,
|
|
1039
|
+
payloads: void 0,
|
|
1040
|
+
requestId: void 0
|
|
1041
|
+
};
|
|
1042
|
+
return {
|
|
1043
|
+
flags: featureFlagDetails.featureFlags,
|
|
1044
|
+
payloads: featureFlagDetails.featureFlagPayloads,
|
|
1045
|
+
requestId: featureFlagDetails.requestId
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
async getFeatureFlagDetailsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
|
|
1049
|
+
await this._initPromise;
|
|
1050
|
+
const extraPayload = {};
|
|
1051
|
+
if (disableGeoip ?? this.disableGeoip) extraPayload["geoip_disable"] = true;
|
|
1052
|
+
if (flagKeysToEvaluate) extraPayload["flag_keys_to_evaluate"] = flagKeysToEvaluate;
|
|
1053
|
+
const flagsResponse = await this.getFlags(distinctId, groups, personProperties, groupProperties, extraPayload);
|
|
1054
|
+
if (void 0 === flagsResponse) return;
|
|
1055
|
+
if (flagsResponse.errorsWhileComputingFlags) console.error("[FEATURE FLAGS] Error while computing feature flags, some flags may be missing or incorrect. Learn more at https://posthog.com/docs/feature-flags/best-practices");
|
|
1056
|
+
if (flagsResponse.quotaLimited?.includes("feature_flags")) {
|
|
1057
|
+
console.warn("[FEATURE FLAGS] Feature flags quota limit exceeded - feature flags unavailable. Learn more about billing limits at https://posthog.com/docs/billing/limits-alerts");
|
|
1058
|
+
return {
|
|
1059
|
+
flags: {},
|
|
1060
|
+
featureFlags: {},
|
|
1061
|
+
featureFlagPayloads: {},
|
|
1062
|
+
requestId: flagsResponse?.requestId
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
return flagsResponse;
|
|
1066
|
+
}
|
|
1067
|
+
async getSurveysStateless() {
|
|
1068
|
+
await this._initPromise;
|
|
1069
|
+
if (true === this.disableSurveys) {
|
|
1070
|
+
this._logger.info("Loading surveys is disabled.");
|
|
1071
|
+
return [];
|
|
1072
|
+
}
|
|
1073
|
+
const url = `${this.host}/api/surveys/?token=${this.apiKey}`;
|
|
1074
|
+
const fetchOptions = {
|
|
1075
|
+
method: "GET",
|
|
1076
|
+
headers: {
|
|
1077
|
+
...this.getCustomHeaders(),
|
|
1078
|
+
"Content-Type": "application/json"
|
|
1079
|
+
}
|
|
1080
|
+
};
|
|
1081
|
+
const response = await this.fetchWithRetry(url, fetchOptions).then((response2) => {
|
|
1082
|
+
if (200 !== response2.status || !response2.json) {
|
|
1083
|
+
const msg = `Surveys API could not be loaded: ${response2.status}`;
|
|
1084
|
+
const error = new Error(msg);
|
|
1085
|
+
this._logger.error(error);
|
|
1086
|
+
this._events.emit("error", new Error(msg));
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
return response2.json();
|
|
1090
|
+
}).catch((error) => {
|
|
1091
|
+
this._logger.error("Surveys API could not be loaded", error);
|
|
1092
|
+
this._events.emit("error", error);
|
|
1093
|
+
});
|
|
1094
|
+
const newSurveys = response?.surveys;
|
|
1095
|
+
if (newSurveys) this._logger.info("Surveys fetched from API: ", JSON.stringify(newSurveys));
|
|
1096
|
+
return newSurveys ?? [];
|
|
1097
|
+
}
|
|
1098
|
+
get props() {
|
|
1099
|
+
if (!this._props) this._props = this.getPersistedProperty(types_PostHogPersistedProperty.Props);
|
|
1100
|
+
return this._props || {};
|
|
1101
|
+
}
|
|
1102
|
+
set props(val) {
|
|
1103
|
+
this._props = val;
|
|
1104
|
+
}
|
|
1105
|
+
async register(properties) {
|
|
1106
|
+
this.wrap(() => {
|
|
1107
|
+
this.props = {
|
|
1108
|
+
...this.props,
|
|
1109
|
+
...properties
|
|
1110
|
+
};
|
|
1111
|
+
this.setPersistedProperty(types_PostHogPersistedProperty.Props, this.props);
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
async unregister(property) {
|
|
1115
|
+
this.wrap(() => {
|
|
1116
|
+
delete this.props[property];
|
|
1117
|
+
this.setPersistedProperty(types_PostHogPersistedProperty.Props, this.props);
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
enqueue(type, _message, options) {
|
|
1121
|
+
this.wrap(() => {
|
|
1122
|
+
if (this.optedOut) return void this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.optIn()");
|
|
1123
|
+
const message = this.prepareMessage(type, _message, options);
|
|
1124
|
+
const queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
|
|
1125
|
+
if (queue.length >= this.maxQueueSize) {
|
|
1126
|
+
queue.shift();
|
|
1127
|
+
this._logger.info("Queue is full, the oldest event is dropped.");
|
|
1128
|
+
}
|
|
1129
|
+
queue.push({
|
|
1130
|
+
message
|
|
1131
|
+
});
|
|
1132
|
+
this.setPersistedProperty(types_PostHogPersistedProperty.Queue, queue);
|
|
1133
|
+
this._events.emit(type, message);
|
|
1134
|
+
if (queue.length >= this.flushAt) this.flushBackground();
|
|
1135
|
+
if (this.flushInterval && !this._flushTimer) this._flushTimer = safeSetTimeout(() => this.flushBackground(), this.flushInterval);
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
async sendImmediate(type, _message, options) {
|
|
1139
|
+
if (this.disabled) return void this._logger.warn("The client is disabled");
|
|
1140
|
+
if (!this._isInitialized) await this._initPromise;
|
|
1141
|
+
if (this.optedOut) return void this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.optIn()");
|
|
1142
|
+
const data = {
|
|
1143
|
+
api_key: this.apiKey,
|
|
1144
|
+
batch: [
|
|
1145
|
+
this.prepareMessage(type, _message, options)
|
|
1146
|
+
],
|
|
1147
|
+
sent_at: currentISOTime()
|
|
1148
|
+
};
|
|
1149
|
+
if (this.historicalMigration) data.historical_migration = true;
|
|
1150
|
+
const payload = JSON.stringify(data);
|
|
1151
|
+
const url = `${this.host}/batch/`;
|
|
1152
|
+
const gzippedPayload = this.disableCompression ? null : await gzipCompress(payload, this.isDebug);
|
|
1153
|
+
const fetchOptions = {
|
|
1154
|
+
method: "POST",
|
|
1155
|
+
headers: {
|
|
1156
|
+
...this.getCustomHeaders(),
|
|
1157
|
+
"Content-Type": "application/json",
|
|
1158
|
+
...null !== gzippedPayload && {
|
|
1159
|
+
"Content-Encoding": "gzip"
|
|
1160
|
+
}
|
|
1161
|
+
},
|
|
1162
|
+
body: gzippedPayload || payload
|
|
1163
|
+
};
|
|
1164
|
+
try {
|
|
1165
|
+
await this.fetchWithRetry(url, fetchOptions);
|
|
1166
|
+
} catch (err) {
|
|
1167
|
+
this._events.emit("error", err);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
prepareMessage(type, _message, options) {
|
|
1171
|
+
const message = {
|
|
1172
|
+
..._message,
|
|
1173
|
+
type,
|
|
1174
|
+
library: this.getLibraryId(),
|
|
1175
|
+
library_version: this.getLibraryVersion(),
|
|
1176
|
+
timestamp: options?.timestamp ? options?.timestamp : currentISOTime(),
|
|
1177
|
+
uuid: options?.uuid ? options.uuid : uuidv7()
|
|
1178
|
+
};
|
|
1179
|
+
const addGeoipDisableProperty = options?.disableGeoip ?? this.disableGeoip;
|
|
1180
|
+
if (addGeoipDisableProperty) {
|
|
1181
|
+
if (!message.properties) message.properties = {};
|
|
1182
|
+
message["properties"]["$geoip_disable"] = true;
|
|
1183
|
+
}
|
|
1184
|
+
if (message.distinctId) {
|
|
1185
|
+
message.distinct_id = message.distinctId;
|
|
1186
|
+
delete message.distinctId;
|
|
1187
|
+
}
|
|
1188
|
+
return message;
|
|
1189
|
+
}
|
|
1190
|
+
clearFlushTimer() {
|
|
1191
|
+
if (this._flushTimer) {
|
|
1192
|
+
clearTimeout(this._flushTimer);
|
|
1193
|
+
this._flushTimer = void 0;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
flushBackground() {
|
|
1197
|
+
this.flush().catch(async (err) => {
|
|
1198
|
+
await logFlushError(err);
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
async flush() {
|
|
1202
|
+
const nextFlushPromise = allSettled([
|
|
1203
|
+
this.flushPromise
|
|
1204
|
+
]).then(() => this._flush());
|
|
1205
|
+
this.flushPromise = nextFlushPromise;
|
|
1206
|
+
this.addPendingPromise(nextFlushPromise);
|
|
1207
|
+
allSettled([
|
|
1208
|
+
nextFlushPromise
|
|
1209
|
+
]).then(() => {
|
|
1210
|
+
if (this.flushPromise === nextFlushPromise) this.flushPromise = null;
|
|
1211
|
+
});
|
|
1212
|
+
return nextFlushPromise;
|
|
1213
|
+
}
|
|
1214
|
+
getCustomHeaders() {
|
|
1215
|
+
const customUserAgent = this.getCustomUserAgent();
|
|
1216
|
+
const headers = {};
|
|
1217
|
+
if (customUserAgent && "" !== customUserAgent) headers["User-Agent"] = customUserAgent;
|
|
1218
|
+
return headers;
|
|
1219
|
+
}
|
|
1220
|
+
async _flush() {
|
|
1221
|
+
this.clearFlushTimer();
|
|
1222
|
+
await this._initPromise;
|
|
1223
|
+
let queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
|
|
1224
|
+
if (!queue.length) return;
|
|
1225
|
+
const sentMessages = [];
|
|
1226
|
+
const originalQueueLength = queue.length;
|
|
1227
|
+
while (queue.length > 0 && sentMessages.length < originalQueueLength) {
|
|
1228
|
+
const batchItems = queue.slice(0, this.maxBatchSize);
|
|
1229
|
+
const batchMessages = batchItems.map((item) => item.message);
|
|
1230
|
+
const persistQueueChange = () => {
|
|
1231
|
+
const refreshedQueue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
|
|
1232
|
+
const newQueue = refreshedQueue.slice(batchItems.length);
|
|
1233
|
+
this.setPersistedProperty(types_PostHogPersistedProperty.Queue, newQueue);
|
|
1234
|
+
queue = newQueue;
|
|
1235
|
+
};
|
|
1236
|
+
const data = {
|
|
1237
|
+
api_key: this.apiKey,
|
|
1238
|
+
batch: batchMessages,
|
|
1239
|
+
sent_at: currentISOTime()
|
|
1240
|
+
};
|
|
1241
|
+
if (this.historicalMigration) data.historical_migration = true;
|
|
1242
|
+
const payload = JSON.stringify(data);
|
|
1243
|
+
const url = `${this.host}/batch/`;
|
|
1244
|
+
const gzippedPayload = this.disableCompression ? null : await gzipCompress(payload, this.isDebug);
|
|
1245
|
+
const fetchOptions = {
|
|
1246
|
+
method: "POST",
|
|
1247
|
+
headers: {
|
|
1248
|
+
...this.getCustomHeaders(),
|
|
1249
|
+
"Content-Type": "application/json",
|
|
1250
|
+
...null !== gzippedPayload && {
|
|
1251
|
+
"Content-Encoding": "gzip"
|
|
1252
|
+
}
|
|
1253
|
+
},
|
|
1254
|
+
body: gzippedPayload || payload
|
|
1255
|
+
};
|
|
1256
|
+
const retryOptions = {
|
|
1257
|
+
retryCheck: (err) => {
|
|
1258
|
+
if (isPostHogFetchContentTooLargeError(err)) return false;
|
|
1259
|
+
return isPostHogFetchError(err);
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
try {
|
|
1263
|
+
await this.fetchWithRetry(url, fetchOptions, retryOptions);
|
|
1264
|
+
} catch (err) {
|
|
1265
|
+
if (isPostHogFetchContentTooLargeError(err) && batchMessages.length > 1) {
|
|
1266
|
+
this.maxBatchSize = Math.max(1, Math.floor(batchMessages.length / 2));
|
|
1267
|
+
this._logger.warn(`Received 413 when sending batch of size ${batchMessages.length}, reducing batch size to ${this.maxBatchSize}`);
|
|
1268
|
+
continue;
|
|
1269
|
+
}
|
|
1270
|
+
if (!(err instanceof PostHogFetchNetworkError)) persistQueueChange();
|
|
1271
|
+
this._events.emit("error", err);
|
|
1272
|
+
throw err;
|
|
1273
|
+
}
|
|
1274
|
+
persistQueueChange();
|
|
1275
|
+
sentMessages.push(...batchMessages);
|
|
1276
|
+
}
|
|
1277
|
+
this._events.emit("flush", sentMessages);
|
|
1278
|
+
}
|
|
1279
|
+
async fetchWithRetry(url, options, retryOptions, requestTimeout) {
|
|
1280
|
+
AbortSignal.timeout ??= function(ms) {
|
|
1281
|
+
const ctrl = new AbortController();
|
|
1282
|
+
setTimeout(() => ctrl.abort(), ms);
|
|
1283
|
+
return ctrl.signal;
|
|
1284
|
+
};
|
|
1285
|
+
const body = options.body ? options.body : "";
|
|
1286
|
+
let reqByteLength = -1;
|
|
1287
|
+
try {
|
|
1288
|
+
reqByteLength = body instanceof Blob ? body.size : Buffer.byteLength(body, STRING_FORMAT);
|
|
1289
|
+
} catch {
|
|
1290
|
+
if (body instanceof Blob) reqByteLength = body.size;
|
|
1291
|
+
else {
|
|
1292
|
+
const encoded = new TextEncoder().encode(body);
|
|
1293
|
+
reqByteLength = encoded.length;
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
return await retriable(async () => {
|
|
1297
|
+
let res = null;
|
|
1298
|
+
try {
|
|
1299
|
+
res = await this.fetch(url, {
|
|
1300
|
+
signal: AbortSignal.timeout(requestTimeout ?? this.requestTimeout),
|
|
1301
|
+
...options
|
|
1302
|
+
});
|
|
1303
|
+
} catch (e) {
|
|
1304
|
+
throw new PostHogFetchNetworkError(e);
|
|
1305
|
+
}
|
|
1306
|
+
const isNoCors = "no-cors" === options.mode;
|
|
1307
|
+
if (!isNoCors && (res.status < 200 || res.status >= 400)) throw new PostHogFetchHttpError(res, reqByteLength);
|
|
1308
|
+
return res;
|
|
1309
|
+
}, {
|
|
1310
|
+
...this._retryOptions,
|
|
1311
|
+
...retryOptions
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
async _shutdown(shutdownTimeoutMs = 3e4) {
|
|
1315
|
+
await this._initPromise;
|
|
1316
|
+
let hasTimedOut = false;
|
|
1317
|
+
this.clearFlushTimer();
|
|
1318
|
+
const doShutdown = async () => {
|
|
1319
|
+
try {
|
|
1320
|
+
await this.promiseQueue.join();
|
|
1321
|
+
while (true) {
|
|
1322
|
+
const queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
|
|
1323
|
+
if (0 === queue.length) break;
|
|
1324
|
+
await this.flush();
|
|
1325
|
+
if (hasTimedOut) break;
|
|
1326
|
+
}
|
|
1327
|
+
} catch (e) {
|
|
1328
|
+
if (!isPostHogFetchError(e)) throw e;
|
|
1329
|
+
await logFlushError(e);
|
|
1330
|
+
}
|
|
1331
|
+
};
|
|
1332
|
+
return Promise.race([
|
|
1333
|
+
new Promise((_, reject) => {
|
|
1334
|
+
safeSetTimeout(() => {
|
|
1335
|
+
this._logger.error("Timed out while shutting down PostHog");
|
|
1336
|
+
hasTimedOut = true;
|
|
1337
|
+
reject("Timeout while shutting down PostHog. Some events may not have been sent.");
|
|
1338
|
+
}, shutdownTimeoutMs);
|
|
1339
|
+
}),
|
|
1340
|
+
doShutdown()
|
|
1341
|
+
]);
|
|
1342
|
+
}
|
|
1343
|
+
async shutdown(shutdownTimeoutMs = 3e4) {
|
|
1344
|
+
if (this.shutdownPromise) this._logger.warn("shutdown() called while already shutting down. shutdown() is meant to be called once before process exit - use flush() for per-request cleanup");
|
|
1345
|
+
else this.shutdownPromise = this._shutdown(shutdownTimeoutMs).finally(() => {
|
|
1346
|
+
this.shutdownPromise = null;
|
|
1347
|
+
});
|
|
1348
|
+
return this.shutdownPromise;
|
|
1349
|
+
}
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
});
|
|
1353
|
+
|
|
1354
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/posthog-core.mjs
|
|
1355
|
+
var init_posthog_core = __esm({
|
|
1356
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/posthog-core.mjs"() {
|
|
1357
|
+
init_featureFlagUtils();
|
|
1358
|
+
init_types();
|
|
1359
|
+
init_posthog_core_stateless();
|
|
1360
|
+
init_uuidv7();
|
|
1361
|
+
init_utils();
|
|
1362
|
+
}
|
|
1363
|
+
});
|
|
1364
|
+
|
|
1365
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
|
|
1366
|
+
function getFilenameToChunkIdMap(stackParser) {
|
|
1367
|
+
const chunkIdMap = globalThis._posthogChunkIds;
|
|
1368
|
+
if (!chunkIdMap) return;
|
|
1369
|
+
const chunkIdKeys = Object.keys(chunkIdMap);
|
|
1370
|
+
if (cachedFilenameChunkIds && chunkIdKeys.length === lastKeysCount) return cachedFilenameChunkIds;
|
|
1371
|
+
lastKeysCount = chunkIdKeys.length;
|
|
1372
|
+
cachedFilenameChunkIds = chunkIdKeys.reduce((acc, stackKey) => {
|
|
1373
|
+
if (!parsedStackResults) parsedStackResults = {};
|
|
1374
|
+
const result = parsedStackResults[stackKey];
|
|
1375
|
+
if (result) acc[result[0]] = result[1];
|
|
1376
|
+
else {
|
|
1377
|
+
const parsedStack = stackParser(stackKey);
|
|
1378
|
+
for (let i = parsedStack.length - 1; i >= 0; i--) {
|
|
1379
|
+
const stackFrame = parsedStack[i];
|
|
1380
|
+
const filename = stackFrame?.filename;
|
|
1381
|
+
const chunkId = chunkIdMap[stackKey];
|
|
1382
|
+
if (filename && chunkId) {
|
|
1383
|
+
acc[filename] = chunkId;
|
|
1384
|
+
parsedStackResults[stackKey] = [
|
|
1385
|
+
filename,
|
|
1386
|
+
chunkId
|
|
1387
|
+
];
|
|
1388
|
+
break;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
return acc;
|
|
1393
|
+
}, {});
|
|
1394
|
+
return cachedFilenameChunkIds;
|
|
1395
|
+
}
|
|
1396
|
+
var parsedStackResults, lastKeysCount, cachedFilenameChunkIds;
|
|
1397
|
+
var init_chunk_ids = __esm({
|
|
1398
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs"() {
|
|
1399
|
+
}
|
|
1400
|
+
});
|
|
1401
|
+
|
|
1402
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
|
|
1403
|
+
var MAX_CAUSE_RECURSION, ErrorPropertiesBuilder;
|
|
1404
|
+
var init_error_properties_builder = __esm({
|
|
1405
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs"() {
|
|
1406
|
+
init_utils();
|
|
1407
|
+
init_chunk_ids();
|
|
1408
|
+
MAX_CAUSE_RECURSION = 4;
|
|
1409
|
+
ErrorPropertiesBuilder = class {
|
|
1410
|
+
constructor(coercers, stackParser, modifiers = []) {
|
|
1411
|
+
this.coercers = coercers;
|
|
1412
|
+
this.stackParser = stackParser;
|
|
1413
|
+
this.modifiers = modifiers;
|
|
1414
|
+
}
|
|
1415
|
+
buildFromUnknown(input, hint = {}) {
|
|
1416
|
+
const providedMechanism = hint && hint.mechanism;
|
|
1417
|
+
const mechanism = providedMechanism || {
|
|
1418
|
+
handled: true,
|
|
1419
|
+
type: "generic"
|
|
1420
|
+
};
|
|
1421
|
+
const coercingContext = this.buildCoercingContext(mechanism, hint, 0);
|
|
1422
|
+
const exceptionWithCause = coercingContext.apply(input);
|
|
1423
|
+
const parsingContext = this.buildParsingContext();
|
|
1424
|
+
const exceptionWithStack = this.parseStacktrace(exceptionWithCause, parsingContext);
|
|
1425
|
+
const exceptionList = this.convertToExceptionList(exceptionWithStack, mechanism);
|
|
1426
|
+
return {
|
|
1427
|
+
$exception_list: exceptionList,
|
|
1428
|
+
$exception_level: "error"
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
async modifyFrames(exceptionList) {
|
|
1432
|
+
for (const exc of exceptionList) if (exc.stacktrace && exc.stacktrace.frames && isArray(exc.stacktrace.frames)) exc.stacktrace.frames = await this.applyModifiers(exc.stacktrace.frames);
|
|
1433
|
+
return exceptionList;
|
|
1434
|
+
}
|
|
1435
|
+
coerceFallback(ctx) {
|
|
1436
|
+
return {
|
|
1437
|
+
type: "Error",
|
|
1438
|
+
value: "Unknown error",
|
|
1439
|
+
stack: ctx.syntheticException?.stack,
|
|
1440
|
+
synthetic: true
|
|
1441
|
+
};
|
|
1442
|
+
}
|
|
1443
|
+
parseStacktrace(err, ctx) {
|
|
1444
|
+
let cause;
|
|
1445
|
+
if (null != err.cause) cause = this.parseStacktrace(err.cause, ctx);
|
|
1446
|
+
let stack;
|
|
1447
|
+
if ("" != err.stack && null != err.stack) stack = this.applyChunkIds(this.stackParser(err.stack, err.synthetic ? 1 : 0), ctx.chunkIdMap);
|
|
1448
|
+
return {
|
|
1449
|
+
...err,
|
|
1450
|
+
cause,
|
|
1451
|
+
stack
|
|
1452
|
+
};
|
|
1453
|
+
}
|
|
1454
|
+
applyChunkIds(frames, chunkIdMap) {
|
|
1455
|
+
return frames.map((frame) => {
|
|
1456
|
+
if (frame.filename && chunkIdMap) frame.chunk_id = chunkIdMap[frame.filename];
|
|
1457
|
+
return frame;
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1460
|
+
applyCoercers(input, ctx) {
|
|
1461
|
+
for (const adapter of this.coercers) if (adapter.match(input)) return adapter.coerce(input, ctx);
|
|
1462
|
+
return this.coerceFallback(ctx);
|
|
1463
|
+
}
|
|
1464
|
+
async applyModifiers(frames) {
|
|
1465
|
+
let newFrames = frames;
|
|
1466
|
+
for (const modifier of this.modifiers) newFrames = await modifier(newFrames);
|
|
1467
|
+
return newFrames;
|
|
1468
|
+
}
|
|
1469
|
+
convertToExceptionList(exceptionWithStack, mechanism) {
|
|
1470
|
+
const currentException = {
|
|
1471
|
+
type: exceptionWithStack.type,
|
|
1472
|
+
value: exceptionWithStack.value,
|
|
1473
|
+
mechanism: {
|
|
1474
|
+
type: mechanism.type ?? "generic",
|
|
1475
|
+
handled: mechanism.handled ?? true,
|
|
1476
|
+
synthetic: exceptionWithStack.synthetic ?? false
|
|
1477
|
+
}
|
|
1478
|
+
};
|
|
1479
|
+
if (exceptionWithStack.stack) currentException.stacktrace = {
|
|
1480
|
+
type: "raw",
|
|
1481
|
+
frames: exceptionWithStack.stack
|
|
1482
|
+
};
|
|
1483
|
+
const exceptionList = [
|
|
1484
|
+
currentException
|
|
1485
|
+
];
|
|
1486
|
+
if (null != exceptionWithStack.cause) exceptionList.push(...this.convertToExceptionList(exceptionWithStack.cause, {
|
|
1487
|
+
...mechanism,
|
|
1488
|
+
handled: true
|
|
1489
|
+
}));
|
|
1490
|
+
return exceptionList;
|
|
1491
|
+
}
|
|
1492
|
+
buildParsingContext() {
|
|
1493
|
+
const context = {
|
|
1494
|
+
chunkIdMap: getFilenameToChunkIdMap(this.stackParser)
|
|
1495
|
+
};
|
|
1496
|
+
return context;
|
|
1497
|
+
}
|
|
1498
|
+
buildCoercingContext(mechanism, hint, depth = 0) {
|
|
1499
|
+
const coerce = (input, depth2) => {
|
|
1500
|
+
if (!(depth2 <= MAX_CAUSE_RECURSION)) return;
|
|
1501
|
+
{
|
|
1502
|
+
const ctx = this.buildCoercingContext(mechanism, hint, depth2);
|
|
1503
|
+
return this.applyCoercers(input, ctx);
|
|
1504
|
+
}
|
|
1505
|
+
};
|
|
1506
|
+
const context = {
|
|
1507
|
+
...hint,
|
|
1508
|
+
syntheticException: 0 == depth ? hint.syntheticException : void 0,
|
|
1509
|
+
mechanism,
|
|
1510
|
+
apply: (input) => coerce(input, depth),
|
|
1511
|
+
next: (input) => coerce(input, depth + 1)
|
|
1512
|
+
};
|
|
1513
|
+
return context;
|
|
1514
|
+
}
|
|
1515
|
+
};
|
|
1516
|
+
}
|
|
1517
|
+
});
|
|
1518
|
+
|
|
1519
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
|
|
1520
|
+
function createFrame(platform, filename, func, lineno, colno) {
|
|
1521
|
+
const frame = {
|
|
1522
|
+
platform,
|
|
1523
|
+
filename,
|
|
1524
|
+
function: "<anonymous>" === func ? UNKNOWN_FUNCTION : func,
|
|
1525
|
+
in_app: true
|
|
1526
|
+
};
|
|
1527
|
+
if (!isUndefined(lineno)) frame.lineno = lineno;
|
|
1528
|
+
if (!isUndefined(colno)) frame.colno = colno;
|
|
1529
|
+
return frame;
|
|
1530
|
+
}
|
|
1531
|
+
var UNKNOWN_FUNCTION;
|
|
1532
|
+
var init_base = __esm({
|
|
1533
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs"() {
|
|
1534
|
+
init_utils();
|
|
1535
|
+
UNKNOWN_FUNCTION = "?";
|
|
1536
|
+
}
|
|
1537
|
+
});
|
|
1538
|
+
|
|
1539
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
|
|
1540
|
+
var extractSafariExtensionDetails;
|
|
1541
|
+
var init_safari = __esm({
|
|
1542
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs"() {
|
|
1543
|
+
init_base();
|
|
1544
|
+
extractSafariExtensionDetails = (func, filename) => {
|
|
1545
|
+
const isSafariExtension = -1 !== func.indexOf("safari-extension");
|
|
1546
|
+
const isSafariWebExtension = -1 !== func.indexOf("safari-web-extension");
|
|
1547
|
+
return isSafariExtension || isSafariWebExtension ? [
|
|
1548
|
+
-1 !== func.indexOf("@") ? func.split("@")[0] : UNKNOWN_FUNCTION,
|
|
1549
|
+
isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`
|
|
1550
|
+
] : [
|
|
1551
|
+
func,
|
|
1552
|
+
filename
|
|
1553
|
+
];
|
|
1554
|
+
};
|
|
1555
|
+
}
|
|
1556
|
+
});
|
|
1557
|
+
|
|
1558
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
|
|
1559
|
+
var chromeRegexNoFnName, chromeRegex, chromeEvalRegex, chromeStackLineParser;
|
|
1560
|
+
var init_chrome = __esm({
|
|
1561
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs"() {
|
|
1562
|
+
init_base();
|
|
1563
|
+
init_safari();
|
|
1564
|
+
chromeRegexNoFnName = /^\s*at (\S+?)(?::(\d+))(?::(\d+))\s*$/i;
|
|
1565
|
+
chromeRegex = /^\s*at (?:(.+?\)(?: \[.+\])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
|
|
1566
|
+
chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
|
|
1567
|
+
chromeStackLineParser = (line, platform) => {
|
|
1568
|
+
const noFnParts = chromeRegexNoFnName.exec(line);
|
|
1569
|
+
if (noFnParts) {
|
|
1570
|
+
const [, filename, line2, col] = noFnParts;
|
|
1571
|
+
return createFrame(platform, filename, UNKNOWN_FUNCTION, +line2, +col);
|
|
1572
|
+
}
|
|
1573
|
+
const parts = chromeRegex.exec(line);
|
|
1574
|
+
if (parts) {
|
|
1575
|
+
const isEval = parts[2] && 0 === parts[2].indexOf("eval");
|
|
1576
|
+
if (isEval) {
|
|
1577
|
+
const subMatch = chromeEvalRegex.exec(parts[2]);
|
|
1578
|
+
if (subMatch) {
|
|
1579
|
+
parts[2] = subMatch[1];
|
|
1580
|
+
parts[3] = subMatch[2];
|
|
1581
|
+
parts[4] = subMatch[3];
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);
|
|
1585
|
+
return createFrame(platform, filename, func, parts[3] ? +parts[3] : void 0, parts[4] ? +parts[4] : void 0);
|
|
1586
|
+
}
|
|
1587
|
+
};
|
|
1588
|
+
}
|
|
1589
|
+
});
|
|
1590
|
+
|
|
1591
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
|
|
1592
|
+
var winjsRegex, winjsStackLineParser;
|
|
1593
|
+
var init_winjs = __esm({
|
|
1594
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs"() {
|
|
1595
|
+
init_base();
|
|
1596
|
+
winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:[-a-z]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
|
|
1597
|
+
winjsStackLineParser = (line, platform) => {
|
|
1598
|
+
const parts = winjsRegex.exec(line);
|
|
1599
|
+
return parts ? createFrame(platform, parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : void 0) : void 0;
|
|
1600
|
+
};
|
|
1601
|
+
}
|
|
1602
|
+
});
|
|
1603
|
+
|
|
1604
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
|
|
1605
|
+
var geckoREgex, geckoEvalRegex, geckoStackLineParser;
|
|
1606
|
+
var init_gecko = __esm({
|
|
1607
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs"() {
|
|
1608
|
+
init_base();
|
|
1609
|
+
init_safari();
|
|
1610
|
+
geckoREgex = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
|
|
1611
|
+
geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
|
|
1612
|
+
geckoStackLineParser = (line, platform) => {
|
|
1613
|
+
const parts = geckoREgex.exec(line);
|
|
1614
|
+
if (parts) {
|
|
1615
|
+
const isEval = parts[3] && parts[3].indexOf(" > eval") > -1;
|
|
1616
|
+
if (isEval) {
|
|
1617
|
+
const subMatch = geckoEvalRegex.exec(parts[3]);
|
|
1618
|
+
if (subMatch) {
|
|
1619
|
+
parts[1] = parts[1] || "eval";
|
|
1620
|
+
parts[3] = subMatch[1];
|
|
1621
|
+
parts[4] = subMatch[2];
|
|
1622
|
+
parts[5] = "";
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
let filename = parts[3];
|
|
1626
|
+
let func = parts[1] || UNKNOWN_FUNCTION;
|
|
1627
|
+
[func, filename] = extractSafariExtensionDetails(func, filename);
|
|
1628
|
+
return createFrame(platform, filename, func, parts[4] ? +parts[4] : void 0, parts[5] ? +parts[5] : void 0);
|
|
1629
|
+
}
|
|
1630
|
+
};
|
|
1631
|
+
}
|
|
1632
|
+
});
|
|
1633
|
+
|
|
1634
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
|
|
1635
|
+
var opera10Regex, opera10StackLineParser, opera11Regex, opera11StackLineParser;
|
|
1636
|
+
var init_opera = __esm({
|
|
1637
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs"() {
|
|
1638
|
+
init_base();
|
|
1639
|
+
opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
|
|
1640
|
+
opera10StackLineParser = (line, platform) => {
|
|
1641
|
+
const parts = opera10Regex.exec(line);
|
|
1642
|
+
return parts ? createFrame(platform, parts[2], parts[3] || UNKNOWN_FUNCTION, +parts[1]) : void 0;
|
|
1643
|
+
};
|
|
1644
|
+
opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\(.*\))? in (.*):\s*$/i;
|
|
1645
|
+
opera11StackLineParser = (line, platform) => {
|
|
1646
|
+
const parts = opera11Regex.exec(line);
|
|
1647
|
+
return parts ? createFrame(platform, parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : void 0;
|
|
1648
|
+
};
|
|
1649
|
+
}
|
|
1650
|
+
});
|
|
1651
|
+
|
|
1652
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
|
|
1653
|
+
function filenameIsInApp(filename, isNative = false) {
|
|
1654
|
+
const isInternal = isNative || filename && !filename.startsWith("/") && !filename.match(/^[A-Z]:/) && !filename.startsWith(".") && !filename.match(/^[a-zA-Z]([a-zA-Z0-9.\-+])*:\/\//);
|
|
1655
|
+
return !isInternal && void 0 !== filename && !filename.includes("node_modules/");
|
|
1656
|
+
}
|
|
1657
|
+
function _parseIntOrUndefined(input) {
|
|
1658
|
+
return parseInt(input || "", 10) || void 0;
|
|
1659
|
+
}
|
|
1660
|
+
var FILENAME_MATCH, FULL_MATCH, nodeStackLineParser;
|
|
1661
|
+
var init_node = __esm({
|
|
1662
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs"() {
|
|
1663
|
+
init_base();
|
|
1664
|
+
FILENAME_MATCH = /^\s*[-]{4,}$/;
|
|
1665
|
+
FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
|
|
1666
|
+
nodeStackLineParser = (line, platform) => {
|
|
1667
|
+
const lineMatch = line.match(FULL_MATCH);
|
|
1668
|
+
if (lineMatch) {
|
|
1669
|
+
let object;
|
|
1670
|
+
let method;
|
|
1671
|
+
let functionName;
|
|
1672
|
+
let typeName;
|
|
1673
|
+
let methodName;
|
|
1674
|
+
if (lineMatch[1]) {
|
|
1675
|
+
functionName = lineMatch[1];
|
|
1676
|
+
let methodStart = functionName.lastIndexOf(".");
|
|
1677
|
+
if ("." === functionName[methodStart - 1]) methodStart--;
|
|
1678
|
+
if (methodStart > 0) {
|
|
1679
|
+
object = functionName.slice(0, methodStart);
|
|
1680
|
+
method = functionName.slice(methodStart + 1);
|
|
1681
|
+
const objectEnd = object.indexOf(".Module");
|
|
1682
|
+
if (objectEnd > 0) {
|
|
1683
|
+
functionName = functionName.slice(objectEnd + 1);
|
|
1684
|
+
object = object.slice(0, objectEnd);
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
typeName = void 0;
|
|
1688
|
+
}
|
|
1689
|
+
if (method) {
|
|
1690
|
+
typeName = object;
|
|
1691
|
+
methodName = method;
|
|
1692
|
+
}
|
|
1693
|
+
if ("<anonymous>" === method) {
|
|
1694
|
+
methodName = void 0;
|
|
1695
|
+
functionName = void 0;
|
|
1696
|
+
}
|
|
1697
|
+
if (void 0 === functionName) {
|
|
1698
|
+
methodName = methodName || UNKNOWN_FUNCTION;
|
|
1699
|
+
functionName = typeName ? `${typeName}.${methodName}` : methodName;
|
|
1700
|
+
}
|
|
1701
|
+
let filename = lineMatch[2]?.startsWith("file://") ? lineMatch[2].slice(7) : lineMatch[2];
|
|
1702
|
+
const isNative = "native" === lineMatch[5];
|
|
1703
|
+
if (filename?.match(/\/[A-Z]:/)) filename = filename.slice(1);
|
|
1704
|
+
if (!filename && lineMatch[5] && !isNative) filename = lineMatch[5];
|
|
1705
|
+
return {
|
|
1706
|
+
filename: filename ? decodeURI(filename) : void 0,
|
|
1707
|
+
module: void 0,
|
|
1708
|
+
function: functionName,
|
|
1709
|
+
lineno: _parseIntOrUndefined(lineMatch[3]),
|
|
1710
|
+
colno: _parseIntOrUndefined(lineMatch[4]),
|
|
1711
|
+
in_app: filenameIsInApp(filename || "", isNative),
|
|
1712
|
+
platform
|
|
1713
|
+
};
|
|
1714
|
+
}
|
|
1715
|
+
if (line.match(FILENAME_MATCH)) return {
|
|
1716
|
+
filename: line,
|
|
1717
|
+
platform
|
|
1718
|
+
};
|
|
1719
|
+
};
|
|
1720
|
+
}
|
|
1721
|
+
});
|
|
1722
|
+
|
|
1723
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
|
|
1724
|
+
function reverseAndStripFrames(stack) {
|
|
1725
|
+
if (!stack.length) return [];
|
|
1726
|
+
const localStack = Array.from(stack);
|
|
1727
|
+
localStack.reverse();
|
|
1728
|
+
return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map((frame) => ({
|
|
1729
|
+
...frame,
|
|
1730
|
+
filename: frame.filename || getLastStackFrame(localStack).filename,
|
|
1731
|
+
function: frame.function || UNKNOWN_FUNCTION
|
|
1732
|
+
}));
|
|
1733
|
+
}
|
|
1734
|
+
function getLastStackFrame(arr) {
|
|
1735
|
+
return arr[arr.length - 1] || {};
|
|
1736
|
+
}
|
|
1737
|
+
function createStackParser(platform, ...parsers) {
|
|
1738
|
+
return (stack, skipFirstLines = 0) => {
|
|
1739
|
+
const frames = [];
|
|
1740
|
+
const lines = stack.split("\n");
|
|
1741
|
+
for (let i = skipFirstLines; i < lines.length; i++) {
|
|
1742
|
+
const line = lines[i];
|
|
1743
|
+
if (line.length > 1024) continue;
|
|
1744
|
+
const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, "$1") : line;
|
|
1745
|
+
if (!cleanedLine.match(/\S*Error: /)) {
|
|
1746
|
+
for (const parser of parsers) {
|
|
1747
|
+
const frame = parser(cleanedLine, platform);
|
|
1748
|
+
if (frame) {
|
|
1749
|
+
frames.push(frame);
|
|
1750
|
+
break;
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
if (frames.length >= STACKTRACE_FRAME_LIMIT) break;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
return reverseAndStripFrames(frames);
|
|
1757
|
+
};
|
|
1758
|
+
}
|
|
1759
|
+
var WEBPACK_ERROR_REGEXP, STACKTRACE_FRAME_LIMIT;
|
|
1760
|
+
var init_parsers = __esm({
|
|
1761
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs"() {
|
|
1762
|
+
init_base();
|
|
1763
|
+
init_chrome();
|
|
1764
|
+
init_winjs();
|
|
1765
|
+
init_gecko();
|
|
1766
|
+
init_opera();
|
|
1767
|
+
init_node();
|
|
1768
|
+
WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
|
|
1769
|
+
STACKTRACE_FRAME_LIMIT = 50;
|
|
1770
|
+
}
|
|
1771
|
+
});
|
|
1772
|
+
|
|
1773
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
|
|
1774
|
+
var DOMExceptionCoercer;
|
|
1775
|
+
var init_dom_exception_coercer = __esm({
|
|
1776
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs"() {
|
|
1777
|
+
init_utils();
|
|
1778
|
+
DOMExceptionCoercer = class {
|
|
1779
|
+
match(err) {
|
|
1780
|
+
return this.isDOMException(err) || this.isDOMError(err);
|
|
1781
|
+
}
|
|
1782
|
+
coerce(err, ctx) {
|
|
1783
|
+
const hasStack = isString(err.stack);
|
|
1784
|
+
return {
|
|
1785
|
+
type: this.getType(err),
|
|
1786
|
+
value: this.getValue(err),
|
|
1787
|
+
stack: hasStack ? err.stack : void 0,
|
|
1788
|
+
cause: err.cause ? ctx.next(err.cause) : void 0,
|
|
1789
|
+
synthetic: false
|
|
1790
|
+
};
|
|
1791
|
+
}
|
|
1792
|
+
getType(candidate) {
|
|
1793
|
+
return this.isDOMError(candidate) ? "DOMError" : "DOMException";
|
|
1794
|
+
}
|
|
1795
|
+
getValue(err) {
|
|
1796
|
+
const name = err.name || (this.isDOMError(err) ? "DOMError" : "DOMException");
|
|
1797
|
+
const message = err.message ? `${name}: ${err.message}` : name;
|
|
1798
|
+
return message;
|
|
1799
|
+
}
|
|
1800
|
+
isDOMException(err) {
|
|
1801
|
+
return isBuiltin(err, "DOMException");
|
|
1802
|
+
}
|
|
1803
|
+
isDOMError(err) {
|
|
1804
|
+
return isBuiltin(err, "DOMError");
|
|
1805
|
+
}
|
|
1806
|
+
};
|
|
1807
|
+
}
|
|
1808
|
+
});
|
|
1809
|
+
|
|
1810
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
|
|
1811
|
+
var ErrorCoercer;
|
|
1812
|
+
var init_error_coercer = __esm({
|
|
1813
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs"() {
|
|
1814
|
+
init_utils();
|
|
1815
|
+
ErrorCoercer = class {
|
|
1816
|
+
match(err) {
|
|
1817
|
+
return isPlainError(err);
|
|
1818
|
+
}
|
|
1819
|
+
coerce(err, ctx) {
|
|
1820
|
+
return {
|
|
1821
|
+
type: this.getType(err),
|
|
1822
|
+
value: this.getMessage(err, ctx),
|
|
1823
|
+
stack: this.getStack(err),
|
|
1824
|
+
cause: err.cause ? ctx.next(err.cause) : void 0,
|
|
1825
|
+
synthetic: false
|
|
1826
|
+
};
|
|
1827
|
+
}
|
|
1828
|
+
getType(err) {
|
|
1829
|
+
return err.name || err.constructor.name;
|
|
1830
|
+
}
|
|
1831
|
+
getMessage(err, _ctx) {
|
|
1832
|
+
const message = err.message;
|
|
1833
|
+
if (message.error && "string" == typeof message.error.message) return String(message.error.message);
|
|
1834
|
+
return String(message);
|
|
1835
|
+
}
|
|
1836
|
+
getStack(err) {
|
|
1837
|
+
return err.stacktrace || err.stack || void 0;
|
|
1838
|
+
}
|
|
1839
|
+
};
|
|
1840
|
+
}
|
|
1841
|
+
});
|
|
1842
|
+
|
|
1843
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
|
|
1844
|
+
var ErrorEventCoercer;
|
|
1845
|
+
var init_error_event_coercer = __esm({
|
|
1846
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs"() {
|
|
1847
|
+
init_utils();
|
|
1848
|
+
ErrorEventCoercer = class {
|
|
1849
|
+
constructor() {
|
|
1850
|
+
}
|
|
1851
|
+
match(err) {
|
|
1852
|
+
return isErrorEvent(err) && void 0 != err.error;
|
|
1853
|
+
}
|
|
1854
|
+
coerce(err, ctx) {
|
|
1855
|
+
const exceptionLike = ctx.apply(err.error);
|
|
1856
|
+
if (!exceptionLike) return {
|
|
1857
|
+
type: "ErrorEvent",
|
|
1858
|
+
value: err.message,
|
|
1859
|
+
stack: ctx.syntheticException?.stack,
|
|
1860
|
+
synthetic: true
|
|
1861
|
+
};
|
|
1862
|
+
return exceptionLike;
|
|
1863
|
+
}
|
|
1864
|
+
};
|
|
1865
|
+
}
|
|
1866
|
+
});
|
|
1867
|
+
|
|
1868
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
|
|
1869
|
+
var ERROR_TYPES_PATTERN, StringCoercer;
|
|
1870
|
+
var init_string_coercer = __esm({
|
|
1871
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs"() {
|
|
1872
|
+
ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
|
|
1873
|
+
StringCoercer = class {
|
|
1874
|
+
match(input) {
|
|
1875
|
+
return "string" == typeof input;
|
|
1876
|
+
}
|
|
1877
|
+
coerce(input, ctx) {
|
|
1878
|
+
const [type, value] = this.getInfos(input);
|
|
1879
|
+
return {
|
|
1880
|
+
type: type ?? "Error",
|
|
1881
|
+
value: value ?? input,
|
|
1882
|
+
stack: ctx.syntheticException?.stack,
|
|
1883
|
+
synthetic: true
|
|
1884
|
+
};
|
|
1885
|
+
}
|
|
1886
|
+
getInfos(candidate) {
|
|
1887
|
+
let type = "Error";
|
|
1888
|
+
let value = candidate;
|
|
1889
|
+
const groups = candidate.match(ERROR_TYPES_PATTERN);
|
|
1890
|
+
if (groups) {
|
|
1891
|
+
type = groups[1];
|
|
1892
|
+
value = groups[2];
|
|
1893
|
+
}
|
|
1894
|
+
return [
|
|
1895
|
+
type,
|
|
1896
|
+
value
|
|
1897
|
+
];
|
|
1898
|
+
}
|
|
1899
|
+
};
|
|
1900
|
+
}
|
|
1901
|
+
});
|
|
1902
|
+
|
|
1903
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/types.mjs
|
|
1904
|
+
var severityLevels;
|
|
1905
|
+
var init_types2 = __esm({
|
|
1906
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/types.mjs"() {
|
|
1907
|
+
severityLevels = [
|
|
1908
|
+
"fatal",
|
|
1909
|
+
"error",
|
|
1910
|
+
"warning",
|
|
1911
|
+
"log",
|
|
1912
|
+
"info",
|
|
1913
|
+
"debug"
|
|
1914
|
+
];
|
|
1915
|
+
}
|
|
1916
|
+
});
|
|
1917
|
+
|
|
1918
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
|
|
1919
|
+
function extractExceptionKeysForMessage(err, maxLength = 40) {
|
|
1920
|
+
const keys = Object.keys(err);
|
|
1921
|
+
keys.sort();
|
|
1922
|
+
if (!keys.length) return "[object has no keys]";
|
|
1923
|
+
for (let i = keys.length; i > 0; i--) {
|
|
1924
|
+
const serialized = keys.slice(0, i).join(", ");
|
|
1925
|
+
if (!(serialized.length > maxLength)) {
|
|
1926
|
+
if (i === keys.length) return serialized;
|
|
1927
|
+
return serialized.length <= maxLength ? serialized : `${serialized.slice(0, maxLength)}...`;
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
return "";
|
|
1931
|
+
}
|
|
1932
|
+
var init_utils2 = __esm({
|
|
1933
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs"() {
|
|
1934
|
+
}
|
|
1935
|
+
});
|
|
1936
|
+
|
|
1937
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
|
|
1938
|
+
var ObjectCoercer;
|
|
1939
|
+
var init_object_coercer = __esm({
|
|
1940
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs"() {
|
|
1941
|
+
init_utils();
|
|
1942
|
+
init_types2();
|
|
1943
|
+
init_utils2();
|
|
1944
|
+
ObjectCoercer = class {
|
|
1945
|
+
match(candidate) {
|
|
1946
|
+
return "object" == typeof candidate && null !== candidate;
|
|
1947
|
+
}
|
|
1948
|
+
coerce(candidate, ctx) {
|
|
1949
|
+
const errorProperty = this.getErrorPropertyFromObject(candidate);
|
|
1950
|
+
if (errorProperty) return ctx.apply(errorProperty);
|
|
1951
|
+
return {
|
|
1952
|
+
type: this.getType(candidate),
|
|
1953
|
+
value: this.getValue(candidate),
|
|
1954
|
+
stack: ctx.syntheticException?.stack,
|
|
1955
|
+
level: this.isSeverityLevel(candidate.level) ? candidate.level : "error",
|
|
1956
|
+
synthetic: true
|
|
1957
|
+
};
|
|
1958
|
+
}
|
|
1959
|
+
getType(err) {
|
|
1960
|
+
return isEvent(err) ? err.constructor.name : "Error";
|
|
1961
|
+
}
|
|
1962
|
+
getValue(err) {
|
|
1963
|
+
if ("name" in err && "string" == typeof err.name) {
|
|
1964
|
+
let message = `'${err.name}' captured as exception`;
|
|
1965
|
+
if ("message" in err && "string" == typeof err.message) message += ` with message: '${err.message}'`;
|
|
1966
|
+
return message;
|
|
1967
|
+
}
|
|
1968
|
+
if ("message" in err && "string" == typeof err.message) return err.message;
|
|
1969
|
+
const className = this.getObjectClassName(err);
|
|
1970
|
+
const keys = extractExceptionKeysForMessage(err);
|
|
1971
|
+
return `${className && "Object" !== className ? `'${className}'` : "Object"} captured as exception with keys: ${keys}`;
|
|
1972
|
+
}
|
|
1973
|
+
isSeverityLevel(x) {
|
|
1974
|
+
return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;
|
|
1975
|
+
}
|
|
1976
|
+
getErrorPropertyFromObject(obj) {
|
|
1977
|
+
for (const prop in obj) if (Object.prototype.hasOwnProperty.call(obj, prop)) {
|
|
1978
|
+
const value = obj[prop];
|
|
1979
|
+
if (isError(value)) return value;
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
getObjectClassName(obj) {
|
|
1983
|
+
try {
|
|
1984
|
+
const prototype = Object.getPrototypeOf(obj);
|
|
1985
|
+
return prototype ? prototype.constructor.name : void 0;
|
|
1986
|
+
} catch (e) {
|
|
1987
|
+
return;
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
};
|
|
1991
|
+
}
|
|
1992
|
+
});
|
|
1993
|
+
|
|
1994
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
|
|
1995
|
+
var EventCoercer;
|
|
1996
|
+
var init_event_coercer = __esm({
|
|
1997
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs"() {
|
|
1998
|
+
init_utils();
|
|
1999
|
+
init_utils2();
|
|
2000
|
+
EventCoercer = class {
|
|
2001
|
+
match(err) {
|
|
2002
|
+
return isEvent(err);
|
|
2003
|
+
}
|
|
2004
|
+
coerce(evt, ctx) {
|
|
2005
|
+
const constructorName = evt.constructor.name;
|
|
2006
|
+
return {
|
|
2007
|
+
type: constructorName,
|
|
2008
|
+
value: `${constructorName} captured as exception with keys: ${extractExceptionKeysForMessage(evt)}`,
|
|
2009
|
+
stack: ctx.syntheticException?.stack,
|
|
2010
|
+
synthetic: true
|
|
2011
|
+
};
|
|
2012
|
+
}
|
|
2013
|
+
};
|
|
2014
|
+
}
|
|
2015
|
+
});
|
|
2016
|
+
|
|
2017
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
|
|
2018
|
+
var PrimitiveCoercer;
|
|
2019
|
+
var init_primitive_coercer = __esm({
|
|
2020
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs"() {
|
|
2021
|
+
init_utils();
|
|
2022
|
+
PrimitiveCoercer = class {
|
|
2023
|
+
match(candidate) {
|
|
2024
|
+
return isPrimitive(candidate);
|
|
2025
|
+
}
|
|
2026
|
+
coerce(value, ctx) {
|
|
2027
|
+
return {
|
|
2028
|
+
type: "Error",
|
|
2029
|
+
value: `Primitive value captured as exception: ${String(value)}`,
|
|
2030
|
+
stack: ctx.syntheticException?.stack,
|
|
2031
|
+
synthetic: true
|
|
2032
|
+
};
|
|
2033
|
+
}
|
|
2034
|
+
};
|
|
2035
|
+
}
|
|
2036
|
+
});
|
|
2037
|
+
|
|
2038
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
|
|
2039
|
+
var PromiseRejectionEventCoercer;
|
|
2040
|
+
var init_promise_rejection_event = __esm({
|
|
2041
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs"() {
|
|
2042
|
+
init_utils();
|
|
2043
|
+
PromiseRejectionEventCoercer = class {
|
|
2044
|
+
match(err) {
|
|
2045
|
+
return isBuiltin(err, "PromiseRejectionEvent");
|
|
2046
|
+
}
|
|
2047
|
+
coerce(err, ctx) {
|
|
2048
|
+
const reason = this.getUnhandledRejectionReason(err);
|
|
2049
|
+
if (isPrimitive(reason)) return {
|
|
2050
|
+
type: "UnhandledRejection",
|
|
2051
|
+
value: `Non-Error promise rejection captured with value: ${String(reason)}`,
|
|
2052
|
+
stack: ctx.syntheticException?.stack,
|
|
2053
|
+
synthetic: true
|
|
2054
|
+
};
|
|
2055
|
+
return ctx.apply(reason);
|
|
2056
|
+
}
|
|
2057
|
+
getUnhandledRejectionReason(error) {
|
|
2058
|
+
if (isPrimitive(error)) return error;
|
|
2059
|
+
try {
|
|
2060
|
+
if ("reason" in error) return error.reason;
|
|
2061
|
+
if ("detail" in error && "reason" in error.detail) return error.detail.reason;
|
|
2062
|
+
} catch {
|
|
2063
|
+
}
|
|
2064
|
+
return error;
|
|
2065
|
+
}
|
|
2066
|
+
};
|
|
2067
|
+
}
|
|
2068
|
+
});
|
|
2069
|
+
|
|
2070
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/index.mjs
|
|
2071
|
+
var init_coercers = __esm({
|
|
2072
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/coercers/index.mjs"() {
|
|
2073
|
+
init_dom_exception_coercer();
|
|
2074
|
+
init_error_coercer();
|
|
2075
|
+
init_error_event_coercer();
|
|
2076
|
+
init_string_coercer();
|
|
2077
|
+
init_object_coercer();
|
|
2078
|
+
init_event_coercer();
|
|
2079
|
+
init_primitive_coercer();
|
|
2080
|
+
init_promise_rejection_event();
|
|
2081
|
+
}
|
|
2082
|
+
});
|
|
2083
|
+
|
|
2084
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/utils.mjs
|
|
2085
|
+
var ReduceableCache;
|
|
2086
|
+
var init_utils3 = __esm({
|
|
2087
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/utils.mjs"() {
|
|
2088
|
+
ReduceableCache = class {
|
|
2089
|
+
constructor(_maxSize) {
|
|
2090
|
+
this._maxSize = _maxSize;
|
|
2091
|
+
this._cache = /* @__PURE__ */ new Map();
|
|
2092
|
+
}
|
|
2093
|
+
get(key) {
|
|
2094
|
+
const value = this._cache.get(key);
|
|
2095
|
+
if (void 0 === value) return;
|
|
2096
|
+
this._cache.delete(key);
|
|
2097
|
+
this._cache.set(key, value);
|
|
2098
|
+
return value;
|
|
2099
|
+
}
|
|
2100
|
+
set(key, value) {
|
|
2101
|
+
this._cache.set(key, value);
|
|
2102
|
+
}
|
|
2103
|
+
reduce() {
|
|
2104
|
+
while (this._cache.size >= this._maxSize) {
|
|
2105
|
+
const value = this._cache.keys().next().value;
|
|
2106
|
+
if (value) this._cache.delete(value);
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
};
|
|
2110
|
+
}
|
|
2111
|
+
});
|
|
2112
|
+
|
|
2113
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/index.mjs
|
|
2114
|
+
var error_tracking_exports = {};
|
|
2115
|
+
__export(error_tracking_exports, {
|
|
2116
|
+
DOMExceptionCoercer: () => DOMExceptionCoercer,
|
|
2117
|
+
ErrorCoercer: () => ErrorCoercer,
|
|
2118
|
+
ErrorEventCoercer: () => ErrorEventCoercer,
|
|
2119
|
+
ErrorPropertiesBuilder: () => ErrorPropertiesBuilder,
|
|
2120
|
+
EventCoercer: () => EventCoercer,
|
|
2121
|
+
ObjectCoercer: () => ObjectCoercer,
|
|
2122
|
+
PrimitiveCoercer: () => PrimitiveCoercer,
|
|
2123
|
+
PromiseRejectionEventCoercer: () => PromiseRejectionEventCoercer,
|
|
2124
|
+
ReduceableCache: () => ReduceableCache,
|
|
2125
|
+
StringCoercer: () => StringCoercer,
|
|
2126
|
+
chromeStackLineParser: () => chromeStackLineParser,
|
|
2127
|
+
createStackParser: () => createStackParser,
|
|
2128
|
+
geckoStackLineParser: () => geckoStackLineParser,
|
|
2129
|
+
nodeStackLineParser: () => nodeStackLineParser,
|
|
2130
|
+
opera10StackLineParser: () => opera10StackLineParser,
|
|
2131
|
+
opera11StackLineParser: () => opera11StackLineParser,
|
|
2132
|
+
reverseAndStripFrames: () => reverseAndStripFrames,
|
|
2133
|
+
winjsStackLineParser: () => winjsStackLineParser
|
|
2134
|
+
});
|
|
2135
|
+
var init_error_tracking = __esm({
|
|
2136
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/error-tracking/index.mjs"() {
|
|
2137
|
+
init_error_properties_builder();
|
|
2138
|
+
init_parsers();
|
|
2139
|
+
init_coercers();
|
|
2140
|
+
init_utils3();
|
|
2141
|
+
}
|
|
2142
|
+
});
|
|
2143
|
+
|
|
2144
|
+
// ../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/index.mjs
|
|
2145
|
+
var init_dist = __esm({
|
|
2146
|
+
"../../node_modules/.pnpm/@posthog+core@1.6.0/node_modules/@posthog/core/dist/index.mjs"() {
|
|
2147
|
+
init_featureFlagUtils();
|
|
2148
|
+
init_uuidv7();
|
|
2149
|
+
init_utils();
|
|
2150
|
+
init_posthog_core();
|
|
2151
|
+
init_posthog_core_stateless();
|
|
2152
|
+
init_types();
|
|
2153
|
+
init_error_tracking();
|
|
2154
|
+
}
|
|
2155
|
+
});
|
|
2156
|
+
async function addSourceContext(frames) {
|
|
2157
|
+
const filesToLines = {};
|
|
2158
|
+
for (let i = frames.length - 1; i >= 0; i--) {
|
|
2159
|
+
const frame = frames[i];
|
|
2160
|
+
const filename = frame?.filename;
|
|
2161
|
+
if (!frame || "string" != typeof filename || "number" != typeof frame.lineno || shouldSkipContextLinesForFile(filename) || shouldSkipContextLinesForFrame(frame)) continue;
|
|
2162
|
+
const filesToLinesOutput = filesToLines[filename];
|
|
2163
|
+
if (!filesToLinesOutput) filesToLines[filename] = [];
|
|
2164
|
+
filesToLines[filename].push(frame.lineno);
|
|
2165
|
+
}
|
|
2166
|
+
const files = Object.keys(filesToLines);
|
|
2167
|
+
if (0 == files.length) return frames;
|
|
2168
|
+
const readlinePromises = [];
|
|
2169
|
+
for (const file of files) {
|
|
2170
|
+
if (LRU_FILE_CONTENTS_FS_READ_FAILED.get(file)) continue;
|
|
2171
|
+
const filesToLineRanges = filesToLines[file];
|
|
2172
|
+
if (!filesToLineRanges) continue;
|
|
2173
|
+
filesToLineRanges.sort((a, b) => a - b);
|
|
2174
|
+
const ranges = makeLineReaderRanges(filesToLineRanges);
|
|
2175
|
+
if (ranges.every((r) => rangeExistsInContentCache(file, r))) continue;
|
|
2176
|
+
const cache = emplace(LRU_FILE_CONTENTS_CACHE, file, {});
|
|
2177
|
+
readlinePromises.push(getContextLinesFromFile(file, ranges, cache));
|
|
2178
|
+
}
|
|
2179
|
+
await Promise.all(readlinePromises).catch(() => {
|
|
2180
|
+
});
|
|
2181
|
+
if (frames && frames.length > 0) addSourceContextToFrames(frames, LRU_FILE_CONTENTS_CACHE);
|
|
2182
|
+
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
2183
|
+
return frames;
|
|
2184
|
+
}
|
|
2185
|
+
function getContextLinesFromFile(path, ranges, output) {
|
|
2186
|
+
return new Promise((resolve) => {
|
|
2187
|
+
const stream = fs.createReadStream(path);
|
|
2188
|
+
const lineReaded = readline.createInterface({
|
|
2189
|
+
input: stream
|
|
2190
|
+
});
|
|
2191
|
+
function destroyStreamAndResolve() {
|
|
2192
|
+
stream.destroy();
|
|
2193
|
+
resolve();
|
|
2194
|
+
}
|
|
2195
|
+
let lineNumber = 0;
|
|
2196
|
+
let currentRangeIndex = 0;
|
|
2197
|
+
const range = ranges[currentRangeIndex];
|
|
2198
|
+
if (void 0 === range) return void destroyStreamAndResolve();
|
|
2199
|
+
let rangeStart = range[0];
|
|
2200
|
+
let rangeEnd = range[1];
|
|
2201
|
+
function onStreamError() {
|
|
2202
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path, 1);
|
|
2203
|
+
lineReaded.close();
|
|
2204
|
+
lineReaded.removeAllListeners();
|
|
2205
|
+
destroyStreamAndResolve();
|
|
2206
|
+
}
|
|
2207
|
+
stream.on("error", onStreamError);
|
|
2208
|
+
lineReaded.on("error", onStreamError);
|
|
2209
|
+
lineReaded.on("close", destroyStreamAndResolve);
|
|
2210
|
+
lineReaded.on("line", (line) => {
|
|
2211
|
+
lineNumber++;
|
|
2212
|
+
if (lineNumber < rangeStart) return;
|
|
2213
|
+
output[lineNumber] = snipLine(line, 0);
|
|
2214
|
+
if (lineNumber >= rangeEnd) {
|
|
2215
|
+
if (currentRangeIndex === ranges.length - 1) {
|
|
2216
|
+
lineReaded.close();
|
|
2217
|
+
lineReaded.removeAllListeners();
|
|
2218
|
+
return;
|
|
2219
|
+
}
|
|
2220
|
+
currentRangeIndex++;
|
|
2221
|
+
const range2 = ranges[currentRangeIndex];
|
|
2222
|
+
if (void 0 === range2) {
|
|
2223
|
+
lineReaded.close();
|
|
2224
|
+
lineReaded.removeAllListeners();
|
|
2225
|
+
return;
|
|
2226
|
+
}
|
|
2227
|
+
rangeStart = range2[0];
|
|
2228
|
+
rangeEnd = range2[1];
|
|
2229
|
+
}
|
|
2230
|
+
});
|
|
2231
|
+
});
|
|
2232
|
+
}
|
|
2233
|
+
function addSourceContextToFrames(frames, cache) {
|
|
2234
|
+
for (const frame of frames) if (frame.filename && void 0 === frame.context_line && "number" == typeof frame.lineno) {
|
|
2235
|
+
const contents = cache.get(frame.filename);
|
|
2236
|
+
if (void 0 === contents) continue;
|
|
2237
|
+
addContextToFrame(frame.lineno, frame, contents);
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
function addContextToFrame(lineno, frame, contents) {
|
|
2241
|
+
if (void 0 === frame.lineno || void 0 === contents) return;
|
|
2242
|
+
frame.pre_context = [];
|
|
2243
|
+
for (let i = makeRangeStart(lineno); i < lineno; i++) {
|
|
2244
|
+
const line = contents[i];
|
|
2245
|
+
if (void 0 === line) return void clearLineContext(frame);
|
|
2246
|
+
frame.pre_context.push(line);
|
|
2247
|
+
}
|
|
2248
|
+
if (void 0 === contents[lineno]) return void clearLineContext(frame);
|
|
2249
|
+
frame.context_line = contents[lineno];
|
|
2250
|
+
const end = makeRangeEnd(lineno);
|
|
2251
|
+
frame.post_context = [];
|
|
2252
|
+
for (let i = lineno + 1; i <= end; i++) {
|
|
2253
|
+
const line = contents[i];
|
|
2254
|
+
if (void 0 === line) break;
|
|
2255
|
+
frame.post_context.push(line);
|
|
2256
|
+
}
|
|
2257
|
+
}
|
|
2258
|
+
function clearLineContext(frame) {
|
|
2259
|
+
delete frame.pre_context;
|
|
2260
|
+
delete frame.context_line;
|
|
2261
|
+
delete frame.post_context;
|
|
2262
|
+
}
|
|
2263
|
+
function shouldSkipContextLinesForFile(path) {
|
|
2264
|
+
return path.startsWith("node:") || path.endsWith(".min.js") || path.endsWith(".min.cjs") || path.endsWith(".min.mjs") || path.startsWith("data:");
|
|
2265
|
+
}
|
|
2266
|
+
function shouldSkipContextLinesForFrame(frame) {
|
|
2267
|
+
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
2268
|
+
if (void 0 !== frame.colno && frame.colno > MAX_CONTEXTLINES_COLNO) return true;
|
|
2269
|
+
return false;
|
|
2270
|
+
}
|
|
2271
|
+
function rangeExistsInContentCache(file, range) {
|
|
2272
|
+
const contents = LRU_FILE_CONTENTS_CACHE.get(file);
|
|
2273
|
+
if (void 0 === contents) return false;
|
|
2274
|
+
for (let i = range[0]; i <= range[1]; i++) if (void 0 === contents[i]) return false;
|
|
2275
|
+
return true;
|
|
2276
|
+
}
|
|
2277
|
+
function makeLineReaderRanges(lines) {
|
|
2278
|
+
if (!lines.length) return [];
|
|
2279
|
+
let i = 0;
|
|
2280
|
+
const line = lines[0];
|
|
2281
|
+
if ("number" != typeof line) return [];
|
|
2282
|
+
let current = makeContextRange(line);
|
|
2283
|
+
const out = [];
|
|
2284
|
+
while (true) {
|
|
2285
|
+
if (i === lines.length - 1) {
|
|
2286
|
+
out.push(current);
|
|
2287
|
+
break;
|
|
2288
|
+
}
|
|
2289
|
+
const next = lines[i + 1];
|
|
2290
|
+
if ("number" != typeof next) break;
|
|
2291
|
+
if (next <= current[1]) current[1] = next + DEFAULT_LINES_OF_CONTEXT;
|
|
2292
|
+
else {
|
|
2293
|
+
out.push(current);
|
|
2294
|
+
current = makeContextRange(next);
|
|
2295
|
+
}
|
|
2296
|
+
i++;
|
|
2297
|
+
}
|
|
2298
|
+
return out;
|
|
2299
|
+
}
|
|
2300
|
+
function makeContextRange(line) {
|
|
2301
|
+
return [
|
|
2302
|
+
makeRangeStart(line),
|
|
2303
|
+
makeRangeEnd(line)
|
|
2304
|
+
];
|
|
2305
|
+
}
|
|
2306
|
+
function makeRangeStart(line) {
|
|
2307
|
+
return Math.max(1, line - DEFAULT_LINES_OF_CONTEXT);
|
|
2308
|
+
}
|
|
2309
|
+
function makeRangeEnd(line) {
|
|
2310
|
+
return line + DEFAULT_LINES_OF_CONTEXT;
|
|
2311
|
+
}
|
|
2312
|
+
function emplace(map, key, contents) {
|
|
2313
|
+
const value = map.get(key);
|
|
2314
|
+
if (void 0 === value) {
|
|
2315
|
+
map.set(key, contents);
|
|
2316
|
+
return contents;
|
|
2317
|
+
}
|
|
2318
|
+
return value;
|
|
2319
|
+
}
|
|
2320
|
+
function snipLine(line, colno) {
|
|
2321
|
+
let newLine = line;
|
|
2322
|
+
const lineLength = newLine.length;
|
|
2323
|
+
if (lineLength <= 150) return newLine;
|
|
2324
|
+
if (colno > lineLength) colno = lineLength;
|
|
2325
|
+
let start = Math.max(colno - 60, 0);
|
|
2326
|
+
if (start < 5) start = 0;
|
|
2327
|
+
let end = Math.min(start + 140, lineLength);
|
|
2328
|
+
if (end > lineLength - 5) end = lineLength;
|
|
2329
|
+
if (end === lineLength) start = Math.max(end - 140, 0);
|
|
2330
|
+
newLine = newLine.slice(start, end);
|
|
2331
|
+
if (start > 0) newLine = `...${newLine}`;
|
|
2332
|
+
if (end < lineLength) newLine += "...";
|
|
2333
|
+
return newLine;
|
|
2334
|
+
}
|
|
2335
|
+
var LRU_FILE_CONTENTS_CACHE, LRU_FILE_CONTENTS_FS_READ_FAILED, DEFAULT_LINES_OF_CONTEXT, MAX_CONTEXTLINES_COLNO, MAX_CONTEXTLINES_LINENO;
|
|
2336
|
+
var init_context_lines_node = __esm({
|
|
2337
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs"() {
|
|
2338
|
+
init_dist();
|
|
2339
|
+
LRU_FILE_CONTENTS_CACHE = new error_tracking_exports.ReduceableCache(25);
|
|
2340
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED = new error_tracking_exports.ReduceableCache(20);
|
|
2341
|
+
DEFAULT_LINES_OF_CONTEXT = 7;
|
|
2342
|
+
MAX_CONTEXTLINES_COLNO = 1e3;
|
|
2343
|
+
MAX_CONTEXTLINES_LINENO = 1e4;
|
|
2344
|
+
}
|
|
2345
|
+
});
|
|
2346
|
+
|
|
2347
|
+
// ../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs
|
|
2348
|
+
function makeUncaughtExceptionHandler(captureFn, onFatalFn) {
|
|
2349
|
+
let calledFatalError = false;
|
|
2350
|
+
return Object.assign((error) => {
|
|
2351
|
+
const userProvidedListenersCount = global.process.listeners("uncaughtException").filter((listener) => "domainUncaughtExceptionClear" !== listener.name && true !== listener._posthogErrorHandler).length;
|
|
2352
|
+
const processWouldExit = 0 === userProvidedListenersCount;
|
|
2353
|
+
captureFn(error, {
|
|
2354
|
+
mechanism: {
|
|
2355
|
+
type: "onuncaughtexception",
|
|
2356
|
+
handled: false
|
|
2357
|
+
}
|
|
2358
|
+
});
|
|
2359
|
+
if (!calledFatalError && processWouldExit) {
|
|
2360
|
+
calledFatalError = true;
|
|
2361
|
+
onFatalFn(error);
|
|
2362
|
+
}
|
|
2363
|
+
}, {
|
|
2364
|
+
_posthogErrorHandler: true
|
|
2365
|
+
});
|
|
2366
|
+
}
|
|
2367
|
+
function addUncaughtExceptionListener(captureFn, onFatalFn) {
|
|
2368
|
+
global.process.on("uncaughtException", makeUncaughtExceptionHandler(captureFn, onFatalFn));
|
|
2369
|
+
}
|
|
2370
|
+
function addUnhandledRejectionListener(captureFn) {
|
|
2371
|
+
global.process.on("unhandledRejection", (reason) => captureFn(reason, {
|
|
2372
|
+
mechanism: {
|
|
2373
|
+
type: "onunhandledrejection",
|
|
2374
|
+
handled: false
|
|
2375
|
+
}
|
|
2376
|
+
}));
|
|
2377
|
+
}
|
|
2378
|
+
var init_autocapture = __esm({
|
|
2379
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs"() {
|
|
2380
|
+
}
|
|
2381
|
+
});
|
|
2382
|
+
|
|
2383
|
+
// ../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/error-tracking/index.mjs
|
|
2384
|
+
var SHUTDOWN_TIMEOUT, ErrorTracking;
|
|
2385
|
+
var init_error_tracking2 = __esm({
|
|
2386
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/error-tracking/index.mjs"() {
|
|
2387
|
+
init_autocapture();
|
|
2388
|
+
init_dist();
|
|
2389
|
+
SHUTDOWN_TIMEOUT = 2e3;
|
|
2390
|
+
ErrorTracking = class _ErrorTracking {
|
|
2391
|
+
constructor(client, options, _logger) {
|
|
2392
|
+
this.client = client;
|
|
2393
|
+
this._exceptionAutocaptureEnabled = options.enableExceptionAutocapture || false;
|
|
2394
|
+
this._logger = _logger;
|
|
2395
|
+
this._rateLimiter = new BucketedRateLimiter({
|
|
2396
|
+
refillRate: 1,
|
|
2397
|
+
bucketSize: 10,
|
|
2398
|
+
refillInterval: 1e4,
|
|
2399
|
+
_logger: this._logger
|
|
2400
|
+
});
|
|
2401
|
+
this.startAutocaptureIfEnabled();
|
|
2402
|
+
}
|
|
2403
|
+
static async buildEventMessage(error, hint, distinctId, additionalProperties) {
|
|
2404
|
+
const properties = {
|
|
2405
|
+
...additionalProperties
|
|
2406
|
+
};
|
|
2407
|
+
if (!distinctId) properties.$process_person_profile = false;
|
|
2408
|
+
const exceptionProperties = this.errorPropertiesBuilder.buildFromUnknown(error, hint);
|
|
2409
|
+
exceptionProperties.$exception_list = await this.errorPropertiesBuilder.modifyFrames(exceptionProperties.$exception_list);
|
|
2410
|
+
return {
|
|
2411
|
+
event: "$exception",
|
|
2412
|
+
distinctId: distinctId || uuidv7(),
|
|
2413
|
+
properties: {
|
|
2414
|
+
...exceptionProperties,
|
|
2415
|
+
...properties
|
|
2416
|
+
}
|
|
2417
|
+
};
|
|
2418
|
+
}
|
|
2419
|
+
startAutocaptureIfEnabled() {
|
|
2420
|
+
if (this.isEnabled()) {
|
|
2421
|
+
addUncaughtExceptionListener(this.onException.bind(this), this.onFatalError.bind(this));
|
|
2422
|
+
addUnhandledRejectionListener(this.onException.bind(this));
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
onException(exception, hint) {
|
|
2426
|
+
this.client.addPendingPromise((async () => {
|
|
2427
|
+
const eventMessage = await _ErrorTracking.buildEventMessage(exception, hint);
|
|
2428
|
+
const exceptionProperties = eventMessage.properties;
|
|
2429
|
+
const exceptionType = exceptionProperties?.$exception_list[0]?.type ?? "Exception";
|
|
2430
|
+
const isRateLimited = this._rateLimiter.consumeRateLimit(exceptionType);
|
|
2431
|
+
if (isRateLimited) return void this._logger.info("Skipping exception capture because of client rate limiting.", {
|
|
2432
|
+
exception: exceptionType
|
|
2433
|
+
});
|
|
2434
|
+
return this.client.capture(eventMessage);
|
|
2435
|
+
})());
|
|
2436
|
+
}
|
|
2437
|
+
async onFatalError(exception) {
|
|
2438
|
+
console.error(exception);
|
|
2439
|
+
await this.client.shutdown(SHUTDOWN_TIMEOUT);
|
|
2440
|
+
process.exit(1);
|
|
2441
|
+
}
|
|
2442
|
+
isEnabled() {
|
|
2443
|
+
return !this.client.isDisabled && this._exceptionAutocaptureEnabled;
|
|
2444
|
+
}
|
|
2445
|
+
shutdown() {
|
|
2446
|
+
this._rateLimiter.stop();
|
|
2447
|
+
}
|
|
2448
|
+
};
|
|
2449
|
+
}
|
|
2450
|
+
});
|
|
2451
|
+
|
|
2452
|
+
// ../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/version.mjs
|
|
2453
|
+
var version;
|
|
2454
|
+
var init_version = __esm({
|
|
2455
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/version.mjs"() {
|
|
2456
|
+
version = "5.14.0";
|
|
2457
|
+
}
|
|
2458
|
+
});
|
|
2459
|
+
|
|
2460
|
+
// ../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/feature-flags/crypto.mjs
|
|
2461
|
+
async function hashSHA1(text) {
|
|
2462
|
+
const subtle = globalThis.crypto?.subtle;
|
|
2463
|
+
if (!subtle) throw new Error("SubtleCrypto API not available");
|
|
2464
|
+
const hashBuffer = await subtle.digest("SHA-1", new TextEncoder().encode(text));
|
|
2465
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
2466
|
+
return hashArray.map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
2467
|
+
}
|
|
2468
|
+
var init_crypto = __esm({
|
|
2469
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/feature-flags/crypto.mjs"() {
|
|
2470
|
+
}
|
|
2471
|
+
});
|
|
2472
|
+
|
|
2473
|
+
// ../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/feature-flags/feature-flags.mjs
|
|
2474
|
+
async function _hash(key, distinctId, salt = "") {
|
|
2475
|
+
const hashString = await hashSHA1(`${key}.${distinctId}${salt}`);
|
|
2476
|
+
return parseInt(hashString.slice(0, 15), 16) / LONG_SCALE;
|
|
2477
|
+
}
|
|
2478
|
+
function matchProperty(property, propertyValues, warnFunction) {
|
|
2479
|
+
const key = property.key;
|
|
2480
|
+
const value = property.value;
|
|
2481
|
+
const operator = property.operator || "exact";
|
|
2482
|
+
if (key in propertyValues) {
|
|
2483
|
+
if ("is_not_set" === operator) throw new InconclusiveMatchError("Operator is_not_set is not supported");
|
|
2484
|
+
} else throw new InconclusiveMatchError(`Property ${key} not found in propertyValues`);
|
|
2485
|
+
const overrideValue = propertyValues[key];
|
|
2486
|
+
if (null == overrideValue && !NULL_VALUES_ALLOWED_OPERATORS.includes(operator)) {
|
|
2487
|
+
if (warnFunction) warnFunction(`Property ${key} cannot have a value of null/undefined with the ${operator} operator`);
|
|
2488
|
+
return false;
|
|
2489
|
+
}
|
|
2490
|
+
function computeExactMatch(value2, overrideValue2) {
|
|
2491
|
+
if (Array.isArray(value2)) return value2.map((val) => String(val).toLowerCase()).includes(String(overrideValue2).toLowerCase());
|
|
2492
|
+
return String(value2).toLowerCase() === String(overrideValue2).toLowerCase();
|
|
2493
|
+
}
|
|
2494
|
+
function compare(lhs, rhs, operator2) {
|
|
2495
|
+
if ("gt" === operator2) return lhs > rhs;
|
|
2496
|
+
if ("gte" === operator2) return lhs >= rhs;
|
|
2497
|
+
if ("lt" === operator2) return lhs < rhs;
|
|
2498
|
+
if ("lte" === operator2) return lhs <= rhs;
|
|
2499
|
+
throw new Error(`Invalid operator: ${operator2}`);
|
|
2500
|
+
}
|
|
2501
|
+
switch (operator) {
|
|
2502
|
+
case "exact":
|
|
2503
|
+
return computeExactMatch(value, overrideValue);
|
|
2504
|
+
case "is_not":
|
|
2505
|
+
return !computeExactMatch(value, overrideValue);
|
|
2506
|
+
case "is_set":
|
|
2507
|
+
return key in propertyValues;
|
|
2508
|
+
case "icontains":
|
|
2509
|
+
return String(overrideValue).toLowerCase().includes(String(value).toLowerCase());
|
|
2510
|
+
case "not_icontains":
|
|
2511
|
+
return !String(overrideValue).toLowerCase().includes(String(value).toLowerCase());
|
|
2512
|
+
case "regex":
|
|
2513
|
+
return isValidRegex(String(value)) && null !== String(overrideValue).match(String(value));
|
|
2514
|
+
case "not_regex":
|
|
2515
|
+
return isValidRegex(String(value)) && null === String(overrideValue).match(String(value));
|
|
2516
|
+
case "gt":
|
|
2517
|
+
case "gte":
|
|
2518
|
+
case "lt":
|
|
2519
|
+
case "lte": {
|
|
2520
|
+
let parsedValue = "number" == typeof value ? value : null;
|
|
2521
|
+
if ("string" == typeof value) try {
|
|
2522
|
+
parsedValue = parseFloat(value);
|
|
2523
|
+
} catch (err) {
|
|
2524
|
+
}
|
|
2525
|
+
if (null == parsedValue || null == overrideValue) return compare(String(overrideValue), String(value), operator);
|
|
2526
|
+
if ("string" == typeof overrideValue) return compare(overrideValue, String(value), operator);
|
|
2527
|
+
return compare(overrideValue, parsedValue, operator);
|
|
2528
|
+
}
|
|
2529
|
+
case "is_date_after":
|
|
2530
|
+
case "is_date_before": {
|
|
2531
|
+
if ("boolean" == typeof value) throw new InconclusiveMatchError("Date operations cannot be performed on boolean values");
|
|
2532
|
+
let parsedDate = relativeDateParseForFeatureFlagMatching(String(value));
|
|
2533
|
+
if (null == parsedDate) parsedDate = convertToDateTime(value);
|
|
2534
|
+
if (null == parsedDate) throw new InconclusiveMatchError(`Invalid date: ${value}`);
|
|
2535
|
+
const overrideDate = convertToDateTime(overrideValue);
|
|
2536
|
+
if ([
|
|
2537
|
+
"is_date_before"
|
|
2538
|
+
].includes(operator)) return overrideDate < parsedDate;
|
|
2539
|
+
return overrideDate > parsedDate;
|
|
2540
|
+
}
|
|
2541
|
+
default:
|
|
2542
|
+
throw new InconclusiveMatchError(`Unknown operator: ${operator}`);
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
function checkCohortExists(cohortId, cohortProperties) {
|
|
2546
|
+
if (!(cohortId in cohortProperties)) throw new RequiresServerEvaluation(`cohort ${cohortId} not found in local cohorts - likely a static cohort that requires server evaluation`);
|
|
2547
|
+
}
|
|
2548
|
+
function matchCohort(property, propertyValues, cohortProperties, debugMode = false) {
|
|
2549
|
+
const cohortId = String(property.value);
|
|
2550
|
+
checkCohortExists(cohortId, cohortProperties);
|
|
2551
|
+
const propertyGroup = cohortProperties[cohortId];
|
|
2552
|
+
return matchPropertyGroup(propertyGroup, propertyValues, cohortProperties, debugMode);
|
|
2553
|
+
}
|
|
2554
|
+
function matchPropertyGroup(propertyGroup, propertyValues, cohortProperties, debugMode = false) {
|
|
2555
|
+
if (!propertyGroup) return true;
|
|
2556
|
+
const propertyGroupType = propertyGroup.type;
|
|
2557
|
+
const properties = propertyGroup.values;
|
|
2558
|
+
if (!properties || 0 === properties.length) return true;
|
|
2559
|
+
let errorMatchingLocally = false;
|
|
2560
|
+
if ("values" in properties[0]) {
|
|
2561
|
+
for (const prop of properties) try {
|
|
2562
|
+
const matches = matchPropertyGroup(prop, propertyValues, cohortProperties, debugMode);
|
|
2563
|
+
if ("AND" === propertyGroupType) {
|
|
2564
|
+
if (!matches) return false;
|
|
2565
|
+
} else if (matches) return true;
|
|
2566
|
+
} catch (err) {
|
|
2567
|
+
if (err instanceof RequiresServerEvaluation) throw err;
|
|
2568
|
+
if (err instanceof InconclusiveMatchError) {
|
|
2569
|
+
if (debugMode) console.debug(`Failed to compute property ${prop} locally: ${err}`);
|
|
2570
|
+
errorMatchingLocally = true;
|
|
2571
|
+
} else throw err;
|
|
2572
|
+
}
|
|
2573
|
+
if (errorMatchingLocally) throw new InconclusiveMatchError("Can't match cohort without a given cohort property value");
|
|
2574
|
+
return "AND" === propertyGroupType;
|
|
2575
|
+
}
|
|
2576
|
+
for (const prop of properties) try {
|
|
2577
|
+
let matches;
|
|
2578
|
+
if ("cohort" === prop.type) matches = matchCohort(prop, propertyValues, cohortProperties, debugMode);
|
|
2579
|
+
else if ("flag" === prop.type) {
|
|
2580
|
+
if (debugMode) console.warn(`[FEATURE FLAGS] Flag dependency filters are not supported in local evaluation. Skipping condition with dependency on flag '${prop.key || "unknown"}'`);
|
|
2581
|
+
continue;
|
|
2582
|
+
} else matches = matchProperty(prop, propertyValues);
|
|
2583
|
+
const negation = prop.negation || false;
|
|
2584
|
+
if ("AND" === propertyGroupType) {
|
|
2585
|
+
if (!matches && !negation) return false;
|
|
2586
|
+
if (matches && negation) return false;
|
|
2587
|
+
} else {
|
|
2588
|
+
if (matches && !negation) return true;
|
|
2589
|
+
if (!matches && negation) return true;
|
|
2590
|
+
}
|
|
2591
|
+
} catch (err) {
|
|
2592
|
+
if (err instanceof RequiresServerEvaluation) throw err;
|
|
2593
|
+
if (err instanceof InconclusiveMatchError) {
|
|
2594
|
+
if (debugMode) console.debug(`Failed to compute property ${prop} locally: ${err}`);
|
|
2595
|
+
errorMatchingLocally = true;
|
|
2596
|
+
} else throw err;
|
|
2597
|
+
}
|
|
2598
|
+
if (errorMatchingLocally) throw new InconclusiveMatchError("can't match cohort without a given cohort property value");
|
|
2599
|
+
return "AND" === propertyGroupType;
|
|
2600
|
+
}
|
|
2601
|
+
function isValidRegex(regex) {
|
|
2602
|
+
try {
|
|
2603
|
+
new RegExp(regex);
|
|
2604
|
+
return true;
|
|
2605
|
+
} catch (err) {
|
|
2606
|
+
return false;
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
function convertToDateTime(value) {
|
|
2610
|
+
if (value instanceof Date) return value;
|
|
2611
|
+
if ("string" == typeof value || "number" == typeof value) {
|
|
2612
|
+
const date = new Date(value);
|
|
2613
|
+
if (!isNaN(date.valueOf())) return date;
|
|
2614
|
+
throw new InconclusiveMatchError(`${value} is in an invalid date format`);
|
|
2615
|
+
}
|
|
2616
|
+
throw new InconclusiveMatchError(`The date provided ${value} must be a string, number, or date object`);
|
|
2617
|
+
}
|
|
2618
|
+
function relativeDateParseForFeatureFlagMatching(value) {
|
|
2619
|
+
const regex = /^-?(?<number>[0-9]+)(?<interval>[a-z])$/;
|
|
2620
|
+
const match = value.match(regex);
|
|
2621
|
+
const parsedDt = new Date((/* @__PURE__ */ new Date()).toISOString());
|
|
2622
|
+
if (!match) return null;
|
|
2623
|
+
{
|
|
2624
|
+
if (!match.groups) return null;
|
|
2625
|
+
const number = parseInt(match.groups["number"]);
|
|
2626
|
+
if (number >= 1e4) return null;
|
|
2627
|
+
const interval = match.groups["interval"];
|
|
2628
|
+
if ("h" == interval) parsedDt.setUTCHours(parsedDt.getUTCHours() - number);
|
|
2629
|
+
else if ("d" == interval) parsedDt.setUTCDate(parsedDt.getUTCDate() - number);
|
|
2630
|
+
else if ("w" == interval) parsedDt.setUTCDate(parsedDt.getUTCDate() - 7 * number);
|
|
2631
|
+
else if ("m" == interval) parsedDt.setUTCMonth(parsedDt.getUTCMonth() - number);
|
|
2632
|
+
else {
|
|
2633
|
+
if ("y" != interval) return null;
|
|
2634
|
+
parsedDt.setUTCFullYear(parsedDt.getUTCFullYear() - number);
|
|
2635
|
+
}
|
|
2636
|
+
return parsedDt;
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
var SIXTY_SECONDS, LONG_SCALE, NULL_VALUES_ALLOWED_OPERATORS, ClientError, InconclusiveMatchError, RequiresServerEvaluation, FeatureFlagsPoller;
|
|
2640
|
+
var init_feature_flags = __esm({
|
|
2641
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/feature-flags/feature-flags.mjs"() {
|
|
2642
|
+
init_dist();
|
|
2643
|
+
init_crypto();
|
|
2644
|
+
SIXTY_SECONDS = 6e4;
|
|
2645
|
+
LONG_SCALE = 1152921504606847e3;
|
|
2646
|
+
NULL_VALUES_ALLOWED_OPERATORS = [
|
|
2647
|
+
"is_not"
|
|
2648
|
+
];
|
|
2649
|
+
ClientError = class _ClientError extends Error {
|
|
2650
|
+
constructor(message) {
|
|
2651
|
+
super();
|
|
2652
|
+
Error.captureStackTrace(this, this.constructor);
|
|
2653
|
+
this.name = "ClientError";
|
|
2654
|
+
this.message = message;
|
|
2655
|
+
Object.setPrototypeOf(this, _ClientError.prototype);
|
|
2656
|
+
}
|
|
2657
|
+
};
|
|
2658
|
+
InconclusiveMatchError = class _InconclusiveMatchError extends Error {
|
|
2659
|
+
constructor(message) {
|
|
2660
|
+
super(message);
|
|
2661
|
+
this.name = this.constructor.name;
|
|
2662
|
+
Error.captureStackTrace(this, this.constructor);
|
|
2663
|
+
Object.setPrototypeOf(this, _InconclusiveMatchError.prototype);
|
|
2664
|
+
}
|
|
2665
|
+
};
|
|
2666
|
+
RequiresServerEvaluation = class _RequiresServerEvaluation extends Error {
|
|
2667
|
+
constructor(message) {
|
|
2668
|
+
super(message);
|
|
2669
|
+
this.name = this.constructor.name;
|
|
2670
|
+
Error.captureStackTrace(this, this.constructor);
|
|
2671
|
+
Object.setPrototypeOf(this, _RequiresServerEvaluation.prototype);
|
|
2672
|
+
}
|
|
2673
|
+
};
|
|
2674
|
+
FeatureFlagsPoller = class {
|
|
2675
|
+
constructor({ pollingInterval, personalApiKey, projectApiKey, timeout, host, customHeaders, ...options }) {
|
|
2676
|
+
this.debugMode = false;
|
|
2677
|
+
this.shouldBeginExponentialBackoff = false;
|
|
2678
|
+
this.backOffCount = 0;
|
|
2679
|
+
this.hasAttemptedCacheLoad = false;
|
|
2680
|
+
this.pollingInterval = pollingInterval;
|
|
2681
|
+
this.personalApiKey = personalApiKey;
|
|
2682
|
+
this.featureFlags = [];
|
|
2683
|
+
this.featureFlagsByKey = {};
|
|
2684
|
+
this.groupTypeMapping = {};
|
|
2685
|
+
this.cohorts = {};
|
|
2686
|
+
this.loadedSuccessfullyOnce = false;
|
|
2687
|
+
this.timeout = timeout;
|
|
2688
|
+
this.projectApiKey = projectApiKey;
|
|
2689
|
+
this.host = host;
|
|
2690
|
+
this.poller = void 0;
|
|
2691
|
+
this.fetch = options.fetch || fetch;
|
|
2692
|
+
this.onError = options.onError;
|
|
2693
|
+
this.customHeaders = customHeaders;
|
|
2694
|
+
this.onLoad = options.onLoad;
|
|
2695
|
+
this.cacheProvider = options.cacheProvider;
|
|
2696
|
+
this.loadFeatureFlags();
|
|
2697
|
+
}
|
|
2698
|
+
debug(enabled = true) {
|
|
2699
|
+
this.debugMode = enabled;
|
|
2700
|
+
}
|
|
2701
|
+
logMsgIfDebug(fn) {
|
|
2702
|
+
if (this.debugMode) fn();
|
|
2703
|
+
}
|
|
2704
|
+
async getFeatureFlag(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}) {
|
|
2705
|
+
await this.loadFeatureFlags();
|
|
2706
|
+
let response;
|
|
2707
|
+
let featureFlag;
|
|
2708
|
+
if (!this.loadedSuccessfullyOnce) return response;
|
|
2709
|
+
featureFlag = this.featureFlagsByKey[key];
|
|
2710
|
+
if (void 0 !== featureFlag) try {
|
|
2711
|
+
const result = await this.computeFlagAndPayloadLocally(featureFlag, distinctId, groups, personProperties, groupProperties);
|
|
2712
|
+
response = result.value;
|
|
2713
|
+
this.logMsgIfDebug(() => console.debug(`Successfully computed flag locally: ${key} -> ${response}`));
|
|
2714
|
+
} catch (e) {
|
|
2715
|
+
if (e instanceof RequiresServerEvaluation || e instanceof InconclusiveMatchError) this.logMsgIfDebug(() => console.debug(`${e.name} when computing flag locally: ${key}: ${e.message}`));
|
|
2716
|
+
else if (e instanceof Error) this.onError?.(new Error(`Error computing flag locally: ${key}: ${e}`));
|
|
2717
|
+
}
|
|
2718
|
+
return response;
|
|
2719
|
+
}
|
|
2720
|
+
async getAllFlagsAndPayloads(distinctId, groups = {}, personProperties = {}, groupProperties = {}, flagKeysToExplicitlyEvaluate) {
|
|
2721
|
+
await this.loadFeatureFlags();
|
|
2722
|
+
const response = {};
|
|
2723
|
+
const payloads = {};
|
|
2724
|
+
let fallbackToFlags = 0 == this.featureFlags.length;
|
|
2725
|
+
const flagsToEvaluate = flagKeysToExplicitlyEvaluate ? flagKeysToExplicitlyEvaluate.map((key) => this.featureFlagsByKey[key]).filter(Boolean) : this.featureFlags;
|
|
2726
|
+
const sharedEvaluationCache = {};
|
|
2727
|
+
await Promise.all(flagsToEvaluate.map(async (flag) => {
|
|
2728
|
+
try {
|
|
2729
|
+
const { value: matchValue, payload: matchPayload } = await this.computeFlagAndPayloadLocally(flag, distinctId, groups, personProperties, groupProperties, void 0, sharedEvaluationCache);
|
|
2730
|
+
response[flag.key] = matchValue;
|
|
2731
|
+
if (matchPayload) payloads[flag.key] = matchPayload;
|
|
2732
|
+
} catch (e) {
|
|
2733
|
+
if (e instanceof RequiresServerEvaluation || e instanceof InconclusiveMatchError) this.logMsgIfDebug(() => console.debug(`${e.name} when computing flag locally: ${flag.key}: ${e.message}`));
|
|
2734
|
+
else if (e instanceof Error) this.onError?.(new Error(`Error computing flag locally: ${flag.key}: ${e}`));
|
|
2735
|
+
fallbackToFlags = true;
|
|
2736
|
+
}
|
|
2737
|
+
}));
|
|
2738
|
+
return {
|
|
2739
|
+
response,
|
|
2740
|
+
payloads,
|
|
2741
|
+
fallbackToFlags
|
|
2742
|
+
};
|
|
2743
|
+
}
|
|
2744
|
+
async computeFlagAndPayloadLocally(flag, distinctId, groups = {}, personProperties = {}, groupProperties = {}, matchValue, evaluationCache, skipLoadCheck = false) {
|
|
2745
|
+
if (!skipLoadCheck) await this.loadFeatureFlags();
|
|
2746
|
+
if (!this.loadedSuccessfullyOnce) return {
|
|
2747
|
+
value: false,
|
|
2748
|
+
payload: null
|
|
2749
|
+
};
|
|
2750
|
+
let flagValue;
|
|
2751
|
+
flagValue = void 0 !== matchValue ? matchValue : await this.computeFlagValueLocally(flag, distinctId, groups, personProperties, groupProperties, evaluationCache);
|
|
2752
|
+
const payload = this.getFeatureFlagPayload(flag.key, flagValue);
|
|
2753
|
+
return {
|
|
2754
|
+
value: flagValue,
|
|
2755
|
+
payload
|
|
2756
|
+
};
|
|
2757
|
+
}
|
|
2758
|
+
async computeFlagValueLocally(flag, distinctId, groups = {}, personProperties = {}, groupProperties = {}, evaluationCache = {}) {
|
|
2759
|
+
if (flag.ensure_experience_continuity) throw new InconclusiveMatchError("Flag has experience continuity enabled");
|
|
2760
|
+
if (!flag.active) return false;
|
|
2761
|
+
const flagFilters = flag.filters || {};
|
|
2762
|
+
const aggregation_group_type_index = flagFilters.aggregation_group_type_index;
|
|
2763
|
+
if (void 0 == aggregation_group_type_index) return await this.matchFeatureFlagProperties(flag, distinctId, personProperties, evaluationCache);
|
|
2764
|
+
{
|
|
2765
|
+
const groupName = this.groupTypeMapping[String(aggregation_group_type_index)];
|
|
2766
|
+
if (!groupName) {
|
|
2767
|
+
this.logMsgIfDebug(() => console.warn(`[FEATURE FLAGS] Unknown group type index ${aggregation_group_type_index} for feature flag ${flag.key}`));
|
|
2768
|
+
throw new InconclusiveMatchError("Flag has unknown group type index");
|
|
2769
|
+
}
|
|
2770
|
+
if (!(groupName in groups)) {
|
|
2771
|
+
this.logMsgIfDebug(() => console.warn(`[FEATURE FLAGS] Can't compute group feature flag: ${flag.key} without group names passed in`));
|
|
2772
|
+
return false;
|
|
2773
|
+
}
|
|
2774
|
+
const focusedGroupProperties = groupProperties[groupName];
|
|
2775
|
+
return await this.matchFeatureFlagProperties(flag, groups[groupName], focusedGroupProperties, evaluationCache);
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
getFeatureFlagPayload(key, flagValue) {
|
|
2779
|
+
let payload = null;
|
|
2780
|
+
if (false !== flagValue && null != flagValue) {
|
|
2781
|
+
if ("boolean" == typeof flagValue) payload = this.featureFlagsByKey?.[key]?.filters?.payloads?.[flagValue.toString()] || null;
|
|
2782
|
+
else if ("string" == typeof flagValue) payload = this.featureFlagsByKey?.[key]?.filters?.payloads?.[flagValue] || null;
|
|
2783
|
+
if (null != payload) {
|
|
2784
|
+
if ("object" == typeof payload) return payload;
|
|
2785
|
+
if ("string" == typeof payload) try {
|
|
2786
|
+
return JSON.parse(payload);
|
|
2787
|
+
} catch {
|
|
2788
|
+
}
|
|
2789
|
+
return payload;
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
return null;
|
|
2793
|
+
}
|
|
2794
|
+
async evaluateFlagDependency(property, distinctId, properties, evaluationCache) {
|
|
2795
|
+
const targetFlagKey = property.key;
|
|
2796
|
+
if (!this.featureFlagsByKey) throw new InconclusiveMatchError("Feature flags not available for dependency evaluation");
|
|
2797
|
+
if (!("dependency_chain" in property)) throw new InconclusiveMatchError(`Flag dependency property for '${targetFlagKey}' is missing required 'dependency_chain' field`);
|
|
2798
|
+
const dependencyChain = property.dependency_chain;
|
|
2799
|
+
if (!Array.isArray(dependencyChain)) throw new InconclusiveMatchError(`Flag dependency property for '${targetFlagKey}' has an invalid 'dependency_chain' (expected array, got ${typeof dependencyChain})`);
|
|
2800
|
+
if (0 === dependencyChain.length) throw new InconclusiveMatchError(`Circular dependency detected for flag '${targetFlagKey}' (empty dependency chain)`);
|
|
2801
|
+
for (const depFlagKey of dependencyChain) {
|
|
2802
|
+
if (!(depFlagKey in evaluationCache)) {
|
|
2803
|
+
const depFlag = this.featureFlagsByKey[depFlagKey];
|
|
2804
|
+
if (depFlag) if (depFlag.active) try {
|
|
2805
|
+
const depResult = await this.matchFeatureFlagProperties(depFlag, distinctId, properties, evaluationCache);
|
|
2806
|
+
evaluationCache[depFlagKey] = depResult;
|
|
2807
|
+
} catch (error) {
|
|
2808
|
+
throw new InconclusiveMatchError(`Error evaluating flag dependency '${depFlagKey}' for flag '${targetFlagKey}': ${error}`);
|
|
2809
|
+
}
|
|
2810
|
+
else evaluationCache[depFlagKey] = false;
|
|
2811
|
+
else throw new InconclusiveMatchError(`Missing flag dependency '${depFlagKey}' for flag '${targetFlagKey}'`);
|
|
2812
|
+
}
|
|
2813
|
+
const cachedResult = evaluationCache[depFlagKey];
|
|
2814
|
+
if (null == cachedResult) throw new InconclusiveMatchError(`Dependency '${depFlagKey}' could not be evaluated`);
|
|
2815
|
+
}
|
|
2816
|
+
const targetFlagValue = evaluationCache[targetFlagKey];
|
|
2817
|
+
return this.flagEvaluatesToExpectedValue(property.value, targetFlagValue);
|
|
2818
|
+
}
|
|
2819
|
+
flagEvaluatesToExpectedValue(expectedValue, flagValue) {
|
|
2820
|
+
if ("boolean" == typeof expectedValue) return expectedValue === flagValue || "string" == typeof flagValue && "" !== flagValue && true === expectedValue;
|
|
2821
|
+
if ("string" == typeof expectedValue) return flagValue === expectedValue;
|
|
2822
|
+
return false;
|
|
2823
|
+
}
|
|
2824
|
+
async matchFeatureFlagProperties(flag, distinctId, properties, evaluationCache = {}) {
|
|
2825
|
+
const flagFilters = flag.filters || {};
|
|
2826
|
+
const flagConditions = flagFilters.groups || [];
|
|
2827
|
+
let isInconclusive = false;
|
|
2828
|
+
let result;
|
|
2829
|
+
for (const condition of flagConditions) try {
|
|
2830
|
+
if (await this.isConditionMatch(flag, distinctId, condition, properties, evaluationCache)) {
|
|
2831
|
+
const variantOverride = condition.variant;
|
|
2832
|
+
const flagVariants = flagFilters.multivariate?.variants || [];
|
|
2833
|
+
result = variantOverride && flagVariants.some((variant) => variant.key === variantOverride) ? variantOverride : await this.getMatchingVariant(flag, distinctId) || true;
|
|
2834
|
+
break;
|
|
2835
|
+
}
|
|
2836
|
+
} catch (e) {
|
|
2837
|
+
if (e instanceof RequiresServerEvaluation) throw e;
|
|
2838
|
+
if (e instanceof InconclusiveMatchError) isInconclusive = true;
|
|
2839
|
+
else throw e;
|
|
2840
|
+
}
|
|
2841
|
+
if (void 0 !== result) return result;
|
|
2842
|
+
if (isInconclusive) throw new InconclusiveMatchError("Can't determine if feature flag is enabled or not with given properties");
|
|
2843
|
+
return false;
|
|
2844
|
+
}
|
|
2845
|
+
async isConditionMatch(flag, distinctId, condition, properties, evaluationCache = {}) {
|
|
2846
|
+
const rolloutPercentage = condition.rollout_percentage;
|
|
2847
|
+
const warnFunction = (msg) => {
|
|
2848
|
+
this.logMsgIfDebug(() => console.warn(msg));
|
|
2849
|
+
};
|
|
2850
|
+
if ((condition.properties || []).length > 0) {
|
|
2851
|
+
for (const prop of condition.properties) {
|
|
2852
|
+
const propertyType = prop.type;
|
|
2853
|
+
let matches = false;
|
|
2854
|
+
matches = "cohort" === propertyType ? matchCohort(prop, properties, this.cohorts, this.debugMode) : "flag" === propertyType ? await this.evaluateFlagDependency(prop, distinctId, properties, evaluationCache) : matchProperty(prop, properties, warnFunction);
|
|
2855
|
+
if (!matches) return false;
|
|
2856
|
+
}
|
|
2857
|
+
if (void 0 == rolloutPercentage) return true;
|
|
2858
|
+
}
|
|
2859
|
+
if (void 0 != rolloutPercentage && await _hash(flag.key, distinctId) > rolloutPercentage / 100) return false;
|
|
2860
|
+
return true;
|
|
2861
|
+
}
|
|
2862
|
+
async getMatchingVariant(flag, distinctId) {
|
|
2863
|
+
const hashValue = await _hash(flag.key, distinctId, "variant");
|
|
2864
|
+
const matchingVariant = this.variantLookupTable(flag).find((variant) => hashValue >= variant.valueMin && hashValue < variant.valueMax);
|
|
2865
|
+
if (matchingVariant) return matchingVariant.key;
|
|
2866
|
+
}
|
|
2867
|
+
variantLookupTable(flag) {
|
|
2868
|
+
const lookupTable = [];
|
|
2869
|
+
let valueMin = 0;
|
|
2870
|
+
let valueMax = 0;
|
|
2871
|
+
const flagFilters = flag.filters || {};
|
|
2872
|
+
const multivariates = flagFilters.multivariate?.variants || [];
|
|
2873
|
+
multivariates.forEach((variant) => {
|
|
2874
|
+
valueMax = valueMin + variant.rollout_percentage / 100;
|
|
2875
|
+
lookupTable.push({
|
|
2876
|
+
valueMin,
|
|
2877
|
+
valueMax,
|
|
2878
|
+
key: variant.key
|
|
2879
|
+
});
|
|
2880
|
+
valueMin = valueMax;
|
|
2881
|
+
});
|
|
2882
|
+
return lookupTable;
|
|
2883
|
+
}
|
|
2884
|
+
updateFlagState(flagData) {
|
|
2885
|
+
this.featureFlags = flagData.flags;
|
|
2886
|
+
this.featureFlagsByKey = flagData.flags.reduce((acc, curr) => (acc[curr.key] = curr, acc), {});
|
|
2887
|
+
this.groupTypeMapping = flagData.groupTypeMapping;
|
|
2888
|
+
this.cohorts = flagData.cohorts;
|
|
2889
|
+
this.loadedSuccessfullyOnce = true;
|
|
2890
|
+
}
|
|
2891
|
+
async loadFromCache(debugMessage) {
|
|
2892
|
+
if (!this.cacheProvider) return false;
|
|
2893
|
+
try {
|
|
2894
|
+
const cached = await this.cacheProvider.getFlagDefinitions();
|
|
2895
|
+
if (cached) {
|
|
2896
|
+
this.updateFlagState(cached);
|
|
2897
|
+
this.logMsgIfDebug(() => console.debug(`[FEATURE FLAGS] ${debugMessage} (${cached.flags.length} flags)`));
|
|
2898
|
+
this.onLoad?.(this.featureFlags.length);
|
|
2899
|
+
return true;
|
|
2900
|
+
}
|
|
2901
|
+
return false;
|
|
2902
|
+
} catch (err) {
|
|
2903
|
+
this.onError?.(new Error(`Failed to load from cache: ${err}`));
|
|
2904
|
+
return false;
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
async loadFeatureFlags(forceReload = false) {
|
|
2908
|
+
if (this.cacheProvider && !this.hasAttemptedCacheLoad) {
|
|
2909
|
+
this.hasAttemptedCacheLoad = true;
|
|
2910
|
+
await this.loadFromCache("Loaded flags from cache");
|
|
2911
|
+
}
|
|
2912
|
+
if (this.loadingPromise) return this.loadingPromise;
|
|
2913
|
+
if (!this.loadedSuccessfullyOnce || forceReload) {
|
|
2914
|
+
this.loadingPromise = this._loadFeatureFlags();
|
|
2915
|
+
await this.loadingPromise;
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
isLocalEvaluationReady() {
|
|
2919
|
+
return (this.loadedSuccessfullyOnce ?? false) && (this.featureFlags?.length ?? 0) > 0;
|
|
2920
|
+
}
|
|
2921
|
+
getPollingInterval() {
|
|
2922
|
+
if (!this.shouldBeginExponentialBackoff) return this.pollingInterval;
|
|
2923
|
+
return Math.min(SIXTY_SECONDS, this.pollingInterval * 2 ** this.backOffCount);
|
|
2924
|
+
}
|
|
2925
|
+
async _loadFeatureFlags() {
|
|
2926
|
+
if (this.poller) {
|
|
2927
|
+
clearTimeout(this.poller);
|
|
2928
|
+
this.poller = void 0;
|
|
2929
|
+
}
|
|
2930
|
+
this.poller = setTimeout(() => this._loadFeatureFlags(), this.getPollingInterval());
|
|
2931
|
+
try {
|
|
2932
|
+
let shouldFetch = true;
|
|
2933
|
+
if (this.cacheProvider) try {
|
|
2934
|
+
shouldFetch = await this.cacheProvider.shouldFetchFlagDefinitions();
|
|
2935
|
+
} catch (err) {
|
|
2936
|
+
this.onError?.(new Error(`Error in shouldFetchFlagDefinitions: ${err}`));
|
|
2937
|
+
}
|
|
2938
|
+
if (!shouldFetch) {
|
|
2939
|
+
const loaded = await this.loadFromCache("Loaded flags from cache (skipped fetch)");
|
|
2940
|
+
if (loaded) return;
|
|
2941
|
+
if (this.loadedSuccessfullyOnce) return;
|
|
2942
|
+
}
|
|
2943
|
+
const res = await this._requestFeatureFlagDefinitions();
|
|
2944
|
+
if (!res) return;
|
|
2945
|
+
switch (res.status) {
|
|
2946
|
+
case 401:
|
|
2947
|
+
this.shouldBeginExponentialBackoff = true;
|
|
2948
|
+
this.backOffCount += 1;
|
|
2949
|
+
throw new ClientError(`Your project key or personal API key is invalid. Setting next polling interval to ${this.getPollingInterval()}ms. More information: https://posthog.com/docs/api#rate-limiting`);
|
|
2950
|
+
case 402:
|
|
2951
|
+
console.warn("[FEATURE FLAGS] Feature flags quota limit exceeded - unsetting all local flags. Learn more about billing limits at https://posthog.com/docs/billing/limits-alerts");
|
|
2952
|
+
this.featureFlags = [];
|
|
2953
|
+
this.featureFlagsByKey = {};
|
|
2954
|
+
this.groupTypeMapping = {};
|
|
2955
|
+
this.cohorts = {};
|
|
2956
|
+
return;
|
|
2957
|
+
case 403:
|
|
2958
|
+
this.shouldBeginExponentialBackoff = true;
|
|
2959
|
+
this.backOffCount += 1;
|
|
2960
|
+
throw new ClientError(`Your personal API key does not have permission to fetch feature flag definitions for local evaluation. Setting next polling interval to ${this.getPollingInterval()}ms. Are you sure you're using the correct personal and Project API key pair? More information: https://posthog.com/docs/api/overview`);
|
|
2961
|
+
case 429:
|
|
2962
|
+
this.shouldBeginExponentialBackoff = true;
|
|
2963
|
+
this.backOffCount += 1;
|
|
2964
|
+
throw new ClientError(`You are being rate limited. Setting next polling interval to ${this.getPollingInterval()}ms. More information: https://posthog.com/docs/api#rate-limiting`);
|
|
2965
|
+
case 200: {
|
|
2966
|
+
const responseJson = await res.json() ?? {};
|
|
2967
|
+
if (!("flags" in responseJson)) return void this.onError?.(new Error(`Invalid response when getting feature flags: ${JSON.stringify(responseJson)}`));
|
|
2968
|
+
const flagData = {
|
|
2969
|
+
flags: responseJson.flags ?? [],
|
|
2970
|
+
groupTypeMapping: responseJson.group_type_mapping || {},
|
|
2971
|
+
cohorts: responseJson.cohorts || {}
|
|
2972
|
+
};
|
|
2973
|
+
this.updateFlagState(flagData);
|
|
2974
|
+
this.shouldBeginExponentialBackoff = false;
|
|
2975
|
+
this.backOffCount = 0;
|
|
2976
|
+
if (this.cacheProvider && shouldFetch) try {
|
|
2977
|
+
await this.cacheProvider.onFlagDefinitionsReceived(flagData);
|
|
2978
|
+
} catch (err) {
|
|
2979
|
+
this.onError?.(new Error(`Failed to store in cache: ${err}`));
|
|
2980
|
+
}
|
|
2981
|
+
this.onLoad?.(this.featureFlags.length);
|
|
2982
|
+
break;
|
|
2983
|
+
}
|
|
2984
|
+
default:
|
|
2985
|
+
return;
|
|
2986
|
+
}
|
|
2987
|
+
} catch (err) {
|
|
2988
|
+
if (err instanceof ClientError) this.onError?.(err);
|
|
2989
|
+
} finally {
|
|
2990
|
+
this.loadingPromise = void 0;
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
getPersonalApiKeyRequestOptions(method = "GET") {
|
|
2994
|
+
return {
|
|
2995
|
+
method,
|
|
2996
|
+
headers: {
|
|
2997
|
+
...this.customHeaders,
|
|
2998
|
+
"Content-Type": "application/json",
|
|
2999
|
+
Authorization: `Bearer ${this.personalApiKey}`
|
|
3000
|
+
}
|
|
3001
|
+
};
|
|
3002
|
+
}
|
|
3003
|
+
_requestFeatureFlagDefinitions() {
|
|
3004
|
+
const url = `${this.host}/api/feature_flag/local_evaluation?token=${this.projectApiKey}&send_cohorts`;
|
|
3005
|
+
const options = this.getPersonalApiKeyRequestOptions();
|
|
3006
|
+
let abortTimeout = null;
|
|
3007
|
+
if (this.timeout && "number" == typeof this.timeout) {
|
|
3008
|
+
const controller = new AbortController();
|
|
3009
|
+
abortTimeout = safeSetTimeout(() => {
|
|
3010
|
+
controller.abort();
|
|
3011
|
+
}, this.timeout);
|
|
3012
|
+
options.signal = controller.signal;
|
|
3013
|
+
}
|
|
3014
|
+
try {
|
|
3015
|
+
const fetch1 = this.fetch;
|
|
3016
|
+
return fetch1(url, options);
|
|
3017
|
+
} finally {
|
|
3018
|
+
clearTimeout(abortTimeout);
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
async stopPoller(timeoutMs = 3e4) {
|
|
3022
|
+
clearTimeout(this.poller);
|
|
3023
|
+
if (this.cacheProvider) try {
|
|
3024
|
+
const shutdownResult = this.cacheProvider.shutdown();
|
|
3025
|
+
if (shutdownResult instanceof Promise) await Promise.race([
|
|
3026
|
+
shutdownResult,
|
|
3027
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`Cache shutdown timeout after ${timeoutMs}ms`)), timeoutMs))
|
|
3028
|
+
]);
|
|
3029
|
+
} catch (err) {
|
|
3030
|
+
this.onError?.(new Error(`Error during cache shutdown: ${err}`));
|
|
3031
|
+
}
|
|
3032
|
+
}
|
|
3033
|
+
};
|
|
3034
|
+
}
|
|
3035
|
+
});
|
|
3036
|
+
|
|
3037
|
+
// ../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/storage-memory.mjs
|
|
3038
|
+
var PostHogMemoryStorage;
|
|
3039
|
+
var init_storage_memory = __esm({
|
|
3040
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/storage-memory.mjs"() {
|
|
3041
|
+
PostHogMemoryStorage = class {
|
|
3042
|
+
getProperty(key) {
|
|
3043
|
+
return this._memoryStorage[key];
|
|
3044
|
+
}
|
|
3045
|
+
setProperty(key, value) {
|
|
3046
|
+
this._memoryStorage[key] = null !== value ? value : void 0;
|
|
3047
|
+
}
|
|
3048
|
+
constructor() {
|
|
3049
|
+
this._memoryStorage = {};
|
|
3050
|
+
}
|
|
3051
|
+
};
|
|
3052
|
+
}
|
|
3053
|
+
});
|
|
3054
|
+
|
|
3055
|
+
// ../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/client.mjs
|
|
3056
|
+
var MINIMUM_POLLING_INTERVAL, THIRTY_SECONDS, MAX_CACHE_SIZE, PostHogBackendClient;
|
|
3057
|
+
var init_client = __esm({
|
|
3058
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/client.mjs"() {
|
|
3059
|
+
init_version();
|
|
3060
|
+
init_dist();
|
|
3061
|
+
init_feature_flags();
|
|
3062
|
+
init_error_tracking2();
|
|
3063
|
+
init_storage_memory();
|
|
3064
|
+
MINIMUM_POLLING_INTERVAL = 100;
|
|
3065
|
+
THIRTY_SECONDS = 3e4;
|
|
3066
|
+
MAX_CACHE_SIZE = 5e4;
|
|
3067
|
+
PostHogBackendClient = class extends PostHogCoreStateless {
|
|
3068
|
+
constructor(apiKey, options = {}) {
|
|
3069
|
+
super(apiKey, options), this._memoryStorage = new PostHogMemoryStorage();
|
|
3070
|
+
this.options = options;
|
|
3071
|
+
this.options.featureFlagsPollingInterval = "number" == typeof options.featureFlagsPollingInterval ? Math.max(options.featureFlagsPollingInterval, MINIMUM_POLLING_INTERVAL) : THIRTY_SECONDS;
|
|
3072
|
+
if (options.personalApiKey) {
|
|
3073
|
+
if (options.personalApiKey.includes("phc_")) throw new Error('Your Personal API key is invalid. These keys are prefixed with "phx_" and can be created in PostHog project settings.');
|
|
3074
|
+
const shouldEnableLocalEvaluation = false !== options.enableLocalEvaluation;
|
|
3075
|
+
if (shouldEnableLocalEvaluation) this.featureFlagsPoller = new FeatureFlagsPoller({
|
|
3076
|
+
pollingInterval: this.options.featureFlagsPollingInterval,
|
|
3077
|
+
personalApiKey: options.personalApiKey,
|
|
3078
|
+
projectApiKey: apiKey,
|
|
3079
|
+
timeout: options.requestTimeout ?? 1e4,
|
|
3080
|
+
host: this.host,
|
|
3081
|
+
fetch: options.fetch,
|
|
3082
|
+
onError: (err) => {
|
|
3083
|
+
this._events.emit("error", err);
|
|
3084
|
+
},
|
|
3085
|
+
onLoad: (count) => {
|
|
3086
|
+
this._events.emit("localEvaluationFlagsLoaded", count);
|
|
3087
|
+
},
|
|
3088
|
+
customHeaders: this.getCustomHeaders(),
|
|
3089
|
+
cacheProvider: options.flagDefinitionCacheProvider
|
|
3090
|
+
});
|
|
3091
|
+
}
|
|
3092
|
+
this.errorTracking = new ErrorTracking(this, options, this._logger);
|
|
3093
|
+
this.distinctIdHasSentFlagCalls = {};
|
|
3094
|
+
this.maxCacheSize = options.maxCacheSize || MAX_CACHE_SIZE;
|
|
3095
|
+
}
|
|
3096
|
+
getPersistedProperty(key) {
|
|
3097
|
+
return this._memoryStorage.getProperty(key);
|
|
3098
|
+
}
|
|
3099
|
+
setPersistedProperty(key, value) {
|
|
3100
|
+
return this._memoryStorage.setProperty(key, value);
|
|
3101
|
+
}
|
|
3102
|
+
fetch(url, options) {
|
|
3103
|
+
return this.options.fetch ? this.options.fetch(url, options) : fetch(url, options);
|
|
3104
|
+
}
|
|
3105
|
+
getLibraryVersion() {
|
|
3106
|
+
return version;
|
|
3107
|
+
}
|
|
3108
|
+
getCustomUserAgent() {
|
|
3109
|
+
return `${this.getLibraryId()}/${this.getLibraryVersion()}`;
|
|
3110
|
+
}
|
|
3111
|
+
enable() {
|
|
3112
|
+
return super.optIn();
|
|
3113
|
+
}
|
|
3114
|
+
disable() {
|
|
3115
|
+
return super.optOut();
|
|
3116
|
+
}
|
|
3117
|
+
debug(enabled = true) {
|
|
3118
|
+
super.debug(enabled);
|
|
3119
|
+
this.featureFlagsPoller?.debug(enabled);
|
|
3120
|
+
}
|
|
3121
|
+
capture(props) {
|
|
3122
|
+
if ("string" == typeof props) this._logger.warn("Called capture() with a string as the first argument when an object was expected.");
|
|
3123
|
+
this.addPendingPromise(this.prepareEventMessage(props).then(({ distinctId, event, properties, options }) => super.captureStateless(distinctId, event, properties, {
|
|
3124
|
+
timestamp: options.timestamp,
|
|
3125
|
+
disableGeoip: options.disableGeoip,
|
|
3126
|
+
uuid: options.uuid
|
|
3127
|
+
})).catch((err) => {
|
|
3128
|
+
if (err) console.error(err);
|
|
3129
|
+
}));
|
|
3130
|
+
}
|
|
3131
|
+
async captureImmediate(props) {
|
|
3132
|
+
if ("string" == typeof props) this._logger.warn("Called captureImmediate() with a string as the first argument when an object was expected.");
|
|
3133
|
+
return this.addPendingPromise(this.prepareEventMessage(props).then(({ distinctId, event, properties, options }) => super.captureStatelessImmediate(distinctId, event, properties, {
|
|
3134
|
+
timestamp: options.timestamp,
|
|
3135
|
+
disableGeoip: options.disableGeoip,
|
|
3136
|
+
uuid: options.uuid
|
|
3137
|
+
})).catch((err) => {
|
|
3138
|
+
if (err) console.error(err);
|
|
3139
|
+
}));
|
|
3140
|
+
}
|
|
3141
|
+
identify({ distinctId, properties, disableGeoip }) {
|
|
3142
|
+
const userPropsOnce = properties?.$set_once;
|
|
3143
|
+
delete properties?.$set_once;
|
|
3144
|
+
const userProps = properties?.$set || properties;
|
|
3145
|
+
super.identifyStateless(distinctId, {
|
|
3146
|
+
$set: userProps,
|
|
3147
|
+
$set_once: userPropsOnce
|
|
3148
|
+
}, {
|
|
3149
|
+
disableGeoip
|
|
3150
|
+
});
|
|
3151
|
+
}
|
|
3152
|
+
async identifyImmediate({ distinctId, properties, disableGeoip }) {
|
|
3153
|
+
const userPropsOnce = properties?.$set_once;
|
|
3154
|
+
delete properties?.$set_once;
|
|
3155
|
+
const userProps = properties?.$set || properties;
|
|
3156
|
+
await super.identifyStatelessImmediate(distinctId, {
|
|
3157
|
+
$set: userProps,
|
|
3158
|
+
$set_once: userPropsOnce
|
|
3159
|
+
}, {
|
|
3160
|
+
disableGeoip
|
|
3161
|
+
});
|
|
3162
|
+
}
|
|
3163
|
+
alias(data) {
|
|
3164
|
+
super.aliasStateless(data.alias, data.distinctId, void 0, {
|
|
3165
|
+
disableGeoip: data.disableGeoip
|
|
3166
|
+
});
|
|
3167
|
+
}
|
|
3168
|
+
async aliasImmediate(data) {
|
|
3169
|
+
await super.aliasStatelessImmediate(data.alias, data.distinctId, void 0, {
|
|
3170
|
+
disableGeoip: data.disableGeoip
|
|
3171
|
+
});
|
|
3172
|
+
}
|
|
3173
|
+
isLocalEvaluationReady() {
|
|
3174
|
+
return this.featureFlagsPoller?.isLocalEvaluationReady() ?? false;
|
|
3175
|
+
}
|
|
3176
|
+
async waitForLocalEvaluationReady(timeoutMs = THIRTY_SECONDS) {
|
|
3177
|
+
if (this.isLocalEvaluationReady()) return true;
|
|
3178
|
+
if (void 0 === this.featureFlagsPoller) return false;
|
|
3179
|
+
return new Promise((resolve) => {
|
|
3180
|
+
const timeout = setTimeout(() => {
|
|
3181
|
+
cleanup();
|
|
3182
|
+
resolve(false);
|
|
3183
|
+
}, timeoutMs);
|
|
3184
|
+
const cleanup = this._events.on("localEvaluationFlagsLoaded", (count) => {
|
|
3185
|
+
clearTimeout(timeout);
|
|
3186
|
+
cleanup();
|
|
3187
|
+
resolve(count > 0);
|
|
3188
|
+
});
|
|
3189
|
+
});
|
|
3190
|
+
}
|
|
3191
|
+
async getFeatureFlag(key, distinctId, options) {
|
|
3192
|
+
const { groups, disableGeoip } = options || {};
|
|
3193
|
+
let { onlyEvaluateLocally, sendFeatureFlagEvents, personProperties, groupProperties } = options || {};
|
|
3194
|
+
const adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
|
|
3195
|
+
personProperties = adjustedProperties.allPersonProperties;
|
|
3196
|
+
groupProperties = adjustedProperties.allGroupProperties;
|
|
3197
|
+
if (void 0 == onlyEvaluateLocally) onlyEvaluateLocally = false;
|
|
3198
|
+
if (void 0 == sendFeatureFlagEvents) sendFeatureFlagEvents = this.options.sendFeatureFlagEvent ?? true;
|
|
3199
|
+
let response = await this.featureFlagsPoller?.getFeatureFlag(key, distinctId, groups, personProperties, groupProperties);
|
|
3200
|
+
const flagWasLocallyEvaluated = void 0 !== response;
|
|
3201
|
+
let requestId;
|
|
3202
|
+
let flagDetail;
|
|
3203
|
+
if (!flagWasLocallyEvaluated && !onlyEvaluateLocally) {
|
|
3204
|
+
const remoteResponse = await super.getFeatureFlagDetailStateless(key, distinctId, groups, personProperties, groupProperties, disableGeoip);
|
|
3205
|
+
if (void 0 === remoteResponse) return;
|
|
3206
|
+
flagDetail = remoteResponse.response;
|
|
3207
|
+
response = getFeatureFlagValue(flagDetail);
|
|
3208
|
+
requestId = remoteResponse?.requestId;
|
|
3209
|
+
}
|
|
3210
|
+
const featureFlagReportedKey = `${key}_${response}`;
|
|
3211
|
+
if (sendFeatureFlagEvents && (!(distinctId in this.distinctIdHasSentFlagCalls) || !this.distinctIdHasSentFlagCalls[distinctId].includes(featureFlagReportedKey))) {
|
|
3212
|
+
if (Object.keys(this.distinctIdHasSentFlagCalls).length >= this.maxCacheSize) this.distinctIdHasSentFlagCalls = {};
|
|
3213
|
+
if (Array.isArray(this.distinctIdHasSentFlagCalls[distinctId])) this.distinctIdHasSentFlagCalls[distinctId].push(featureFlagReportedKey);
|
|
3214
|
+
else this.distinctIdHasSentFlagCalls[distinctId] = [
|
|
3215
|
+
featureFlagReportedKey
|
|
3216
|
+
];
|
|
3217
|
+
this.capture({
|
|
3218
|
+
distinctId,
|
|
3219
|
+
event: "$feature_flag_called",
|
|
3220
|
+
properties: {
|
|
3221
|
+
$feature_flag: key,
|
|
3222
|
+
$feature_flag_response: response,
|
|
3223
|
+
$feature_flag_id: flagDetail?.metadata?.id,
|
|
3224
|
+
$feature_flag_version: flagDetail?.metadata?.version,
|
|
3225
|
+
$feature_flag_reason: flagDetail?.reason?.description ?? flagDetail?.reason?.code,
|
|
3226
|
+
locally_evaluated: flagWasLocallyEvaluated,
|
|
3227
|
+
[`$feature/${key}`]: response,
|
|
3228
|
+
$feature_flag_request_id: requestId
|
|
3229
|
+
},
|
|
3230
|
+
groups,
|
|
3231
|
+
disableGeoip
|
|
3232
|
+
});
|
|
3233
|
+
}
|
|
3234
|
+
return response;
|
|
3235
|
+
}
|
|
3236
|
+
async getFeatureFlagPayload(key, distinctId, matchValue, options) {
|
|
3237
|
+
const { groups, disableGeoip } = options || {};
|
|
3238
|
+
let { onlyEvaluateLocally, personProperties, groupProperties } = options || {};
|
|
3239
|
+
const adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
|
|
3240
|
+
personProperties = adjustedProperties.allPersonProperties;
|
|
3241
|
+
groupProperties = adjustedProperties.allGroupProperties;
|
|
3242
|
+
let response;
|
|
3243
|
+
const localEvaluationEnabled = void 0 !== this.featureFlagsPoller;
|
|
3244
|
+
if (localEvaluationEnabled) {
|
|
3245
|
+
await this.featureFlagsPoller?.loadFeatureFlags();
|
|
3246
|
+
const flag = this.featureFlagsPoller?.featureFlagsByKey[key];
|
|
3247
|
+
if (flag) try {
|
|
3248
|
+
const result = await this.featureFlagsPoller?.computeFlagAndPayloadLocally(flag, distinctId, groups, personProperties, groupProperties, matchValue);
|
|
3249
|
+
if (result) {
|
|
3250
|
+
matchValue = result.value;
|
|
3251
|
+
response = result.payload;
|
|
3252
|
+
}
|
|
3253
|
+
} catch (e) {
|
|
3254
|
+
if (e instanceof RequiresServerEvaluation || e instanceof InconclusiveMatchError) this._logger?.info(`${e.name} when computing flag locally: ${flag.key}: ${e.message}`);
|
|
3255
|
+
else throw e;
|
|
3256
|
+
}
|
|
3257
|
+
}
|
|
3258
|
+
if (void 0 == onlyEvaluateLocally) onlyEvaluateLocally = false;
|
|
3259
|
+
const payloadWasLocallyEvaluated = void 0 !== response;
|
|
3260
|
+
if (!payloadWasLocallyEvaluated && !onlyEvaluateLocally) response = await super.getFeatureFlagPayloadStateless(key, distinctId, groups, personProperties, groupProperties, disableGeoip);
|
|
3261
|
+
return response;
|
|
3262
|
+
}
|
|
3263
|
+
async getRemoteConfigPayload(flagKey) {
|
|
3264
|
+
if (!this.options.personalApiKey) throw new Error("Personal API key is required for remote config payload decryption");
|
|
3265
|
+
const response = await this._requestRemoteConfigPayload(flagKey);
|
|
3266
|
+
if (!response) return;
|
|
3267
|
+
const parsed = await response.json();
|
|
3268
|
+
if ("string" == typeof parsed) try {
|
|
3269
|
+
return JSON.parse(parsed);
|
|
3270
|
+
} catch (e) {
|
|
3271
|
+
}
|
|
3272
|
+
return parsed;
|
|
3273
|
+
}
|
|
3274
|
+
async isFeatureEnabled(key, distinctId, options) {
|
|
3275
|
+
const feat = await this.getFeatureFlag(key, distinctId, options);
|
|
3276
|
+
if (void 0 === feat) return;
|
|
3277
|
+
return !!feat || false;
|
|
3278
|
+
}
|
|
3279
|
+
async getAllFlags(distinctId, options) {
|
|
3280
|
+
const response = await this.getAllFlagsAndPayloads(distinctId, options);
|
|
3281
|
+
return response.featureFlags || {};
|
|
3282
|
+
}
|
|
3283
|
+
async getAllFlagsAndPayloads(distinctId, options) {
|
|
3284
|
+
const { groups, disableGeoip, flagKeys } = options || {};
|
|
3285
|
+
let { onlyEvaluateLocally, personProperties, groupProperties } = options || {};
|
|
3286
|
+
const adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
|
|
3287
|
+
personProperties = adjustedProperties.allPersonProperties;
|
|
3288
|
+
groupProperties = adjustedProperties.allGroupProperties;
|
|
3289
|
+
if (void 0 == onlyEvaluateLocally) onlyEvaluateLocally = false;
|
|
3290
|
+
const localEvaluationResult = await this.featureFlagsPoller?.getAllFlagsAndPayloads(distinctId, groups, personProperties, groupProperties, flagKeys);
|
|
3291
|
+
let featureFlags = {};
|
|
3292
|
+
let featureFlagPayloads = {};
|
|
3293
|
+
let fallbackToFlags = true;
|
|
3294
|
+
if (localEvaluationResult) {
|
|
3295
|
+
featureFlags = localEvaluationResult.response;
|
|
3296
|
+
featureFlagPayloads = localEvaluationResult.payloads;
|
|
3297
|
+
fallbackToFlags = localEvaluationResult.fallbackToFlags;
|
|
3298
|
+
}
|
|
3299
|
+
if (fallbackToFlags && !onlyEvaluateLocally) {
|
|
3300
|
+
const remoteEvaluationResult = await super.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeys);
|
|
3301
|
+
featureFlags = {
|
|
3302
|
+
...featureFlags,
|
|
3303
|
+
...remoteEvaluationResult.flags || {}
|
|
3304
|
+
};
|
|
3305
|
+
featureFlagPayloads = {
|
|
3306
|
+
...featureFlagPayloads,
|
|
3307
|
+
...remoteEvaluationResult.payloads || {}
|
|
3308
|
+
};
|
|
3309
|
+
}
|
|
3310
|
+
return {
|
|
3311
|
+
featureFlags,
|
|
3312
|
+
featureFlagPayloads
|
|
3313
|
+
};
|
|
3314
|
+
}
|
|
3315
|
+
groupIdentify({ groupType, groupKey, properties, distinctId, disableGeoip }) {
|
|
3316
|
+
super.groupIdentifyStateless(groupType, groupKey, properties, {
|
|
3317
|
+
disableGeoip
|
|
3318
|
+
}, distinctId);
|
|
3319
|
+
}
|
|
3320
|
+
async reloadFeatureFlags() {
|
|
3321
|
+
await this.featureFlagsPoller?.loadFeatureFlags(true);
|
|
3322
|
+
}
|
|
3323
|
+
async _shutdown(shutdownTimeoutMs) {
|
|
3324
|
+
this.featureFlagsPoller?.stopPoller(shutdownTimeoutMs);
|
|
3325
|
+
this.errorTracking.shutdown();
|
|
3326
|
+
return super._shutdown(shutdownTimeoutMs);
|
|
3327
|
+
}
|
|
3328
|
+
async _requestRemoteConfigPayload(flagKey) {
|
|
3329
|
+
if (!this.options.personalApiKey) return;
|
|
3330
|
+
const url = `${this.host}/api/projects/@current/feature_flags/${flagKey}/remote_config?token=${encodeURIComponent(this.apiKey)}`;
|
|
3331
|
+
const options = {
|
|
3332
|
+
method: "GET",
|
|
3333
|
+
headers: {
|
|
3334
|
+
...this.getCustomHeaders(),
|
|
3335
|
+
"Content-Type": "application/json",
|
|
3336
|
+
Authorization: `Bearer ${this.options.personalApiKey}`
|
|
3337
|
+
}
|
|
3338
|
+
};
|
|
3339
|
+
let abortTimeout = null;
|
|
3340
|
+
if (this.options.requestTimeout && "number" == typeof this.options.requestTimeout) {
|
|
3341
|
+
const controller = new AbortController();
|
|
3342
|
+
abortTimeout = safeSetTimeout(() => {
|
|
3343
|
+
controller.abort();
|
|
3344
|
+
}, this.options.requestTimeout);
|
|
3345
|
+
options.signal = controller.signal;
|
|
3346
|
+
}
|
|
3347
|
+
try {
|
|
3348
|
+
return await this.fetch(url, options);
|
|
3349
|
+
} catch (error) {
|
|
3350
|
+
this._events.emit("error", error);
|
|
3351
|
+
return;
|
|
3352
|
+
} finally {
|
|
3353
|
+
if (abortTimeout) clearTimeout(abortTimeout);
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
extractPropertiesFromEvent(eventProperties, groups) {
|
|
3357
|
+
if (!eventProperties) return {
|
|
3358
|
+
personProperties: {},
|
|
3359
|
+
groupProperties: {}
|
|
3360
|
+
};
|
|
3361
|
+
const personProperties = {};
|
|
3362
|
+
const groupProperties = {};
|
|
3363
|
+
for (const [key, value] of Object.entries(eventProperties)) if (isPlainObject(value) && groups && key in groups) {
|
|
3364
|
+
const groupProps = {};
|
|
3365
|
+
for (const [groupKey, groupValue] of Object.entries(value)) groupProps[String(groupKey)] = String(groupValue);
|
|
3366
|
+
groupProperties[String(key)] = groupProps;
|
|
3367
|
+
} else personProperties[String(key)] = String(value);
|
|
3368
|
+
return {
|
|
3369
|
+
personProperties,
|
|
3370
|
+
groupProperties
|
|
3371
|
+
};
|
|
3372
|
+
}
|
|
3373
|
+
async getFeatureFlagsForEvent(distinctId, groups, disableGeoip, sendFeatureFlagsOptions) {
|
|
3374
|
+
const finalPersonProperties = sendFeatureFlagsOptions?.personProperties || {};
|
|
3375
|
+
const finalGroupProperties = sendFeatureFlagsOptions?.groupProperties || {};
|
|
3376
|
+
const flagKeys = sendFeatureFlagsOptions?.flagKeys;
|
|
3377
|
+
const onlyEvaluateLocally = sendFeatureFlagsOptions?.onlyEvaluateLocally ?? false;
|
|
3378
|
+
if (onlyEvaluateLocally) if (!((this.featureFlagsPoller?.featureFlags?.length || 0) > 0)) return {};
|
|
3379
|
+
else {
|
|
3380
|
+
const groupsWithStringValues = {};
|
|
3381
|
+
for (const [key, value] of Object.entries(groups || {})) groupsWithStringValues[key] = String(value);
|
|
3382
|
+
return await this.getAllFlags(distinctId, {
|
|
3383
|
+
groups: groupsWithStringValues,
|
|
3384
|
+
personProperties: finalPersonProperties,
|
|
3385
|
+
groupProperties: finalGroupProperties,
|
|
3386
|
+
disableGeoip,
|
|
3387
|
+
onlyEvaluateLocally: true,
|
|
3388
|
+
flagKeys
|
|
3389
|
+
});
|
|
3390
|
+
}
|
|
3391
|
+
if ((this.featureFlagsPoller?.featureFlags?.length || 0) > 0) {
|
|
3392
|
+
const groupsWithStringValues = {};
|
|
3393
|
+
for (const [key, value] of Object.entries(groups || {})) groupsWithStringValues[key] = String(value);
|
|
3394
|
+
return await this.getAllFlags(distinctId, {
|
|
3395
|
+
groups: groupsWithStringValues,
|
|
3396
|
+
personProperties: finalPersonProperties,
|
|
3397
|
+
groupProperties: finalGroupProperties,
|
|
3398
|
+
disableGeoip,
|
|
3399
|
+
onlyEvaluateLocally: true,
|
|
3400
|
+
flagKeys
|
|
3401
|
+
});
|
|
3402
|
+
}
|
|
3403
|
+
return (await super.getFeatureFlagsStateless(distinctId, groups, finalPersonProperties, finalGroupProperties, disableGeoip)).flags;
|
|
3404
|
+
}
|
|
3405
|
+
addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties) {
|
|
3406
|
+
const allPersonProperties = {
|
|
3407
|
+
distinct_id: distinctId,
|
|
3408
|
+
...personProperties || {}
|
|
3409
|
+
};
|
|
3410
|
+
const allGroupProperties = {};
|
|
3411
|
+
if (groups) for (const groupName of Object.keys(groups)) allGroupProperties[groupName] = {
|
|
3412
|
+
$group_key: groups[groupName],
|
|
3413
|
+
...groupProperties?.[groupName] || {}
|
|
3414
|
+
};
|
|
3415
|
+
return {
|
|
3416
|
+
allPersonProperties,
|
|
3417
|
+
allGroupProperties
|
|
3418
|
+
};
|
|
3419
|
+
}
|
|
3420
|
+
captureException(error, distinctId, additionalProperties) {
|
|
3421
|
+
const syntheticException = new Error("PostHog syntheticException");
|
|
3422
|
+
this.addPendingPromise(ErrorTracking.buildEventMessage(error, {
|
|
3423
|
+
syntheticException
|
|
3424
|
+
}, distinctId, additionalProperties).then((msg) => this.capture(msg)));
|
|
3425
|
+
}
|
|
3426
|
+
async captureExceptionImmediate(error, distinctId, additionalProperties) {
|
|
3427
|
+
const syntheticException = new Error("PostHog syntheticException");
|
|
3428
|
+
this.addPendingPromise(ErrorTracking.buildEventMessage(error, {
|
|
3429
|
+
syntheticException
|
|
3430
|
+
}, distinctId, additionalProperties).then((msg) => this.captureImmediate(msg)));
|
|
3431
|
+
}
|
|
3432
|
+
async prepareEventMessage(props) {
|
|
3433
|
+
const { distinctId, event, properties, groups, sendFeatureFlags, timestamp, disableGeoip, uuid } = props;
|
|
3434
|
+
const eventMessage = this._runBeforeSend({
|
|
3435
|
+
distinctId,
|
|
3436
|
+
event,
|
|
3437
|
+
properties,
|
|
3438
|
+
groups,
|
|
3439
|
+
sendFeatureFlags,
|
|
3440
|
+
timestamp,
|
|
3441
|
+
disableGeoip,
|
|
3442
|
+
uuid
|
|
3443
|
+
});
|
|
3444
|
+
if (!eventMessage) return Promise.reject(null);
|
|
3445
|
+
const eventProperties = await Promise.resolve().then(async () => {
|
|
3446
|
+
if (sendFeatureFlags) {
|
|
3447
|
+
const sendFeatureFlagsOptions = "object" == typeof sendFeatureFlags ? sendFeatureFlags : void 0;
|
|
3448
|
+
return await this.getFeatureFlagsForEvent(distinctId, groups, disableGeoip, sendFeatureFlagsOptions);
|
|
3449
|
+
}
|
|
3450
|
+
return {};
|
|
3451
|
+
}).then((flags) => {
|
|
3452
|
+
const additionalProperties = {};
|
|
3453
|
+
if (flags) for (const [feature, variant] of Object.entries(flags)) additionalProperties[`$feature/${feature}`] = variant;
|
|
3454
|
+
const activeFlags = Object.keys(flags || {}).filter((flag) => flags?.[flag] !== false).sort();
|
|
3455
|
+
if (activeFlags.length > 0) additionalProperties["$active_feature_flags"] = activeFlags;
|
|
3456
|
+
return additionalProperties;
|
|
3457
|
+
}).catch(() => ({})).then((additionalProperties) => {
|
|
3458
|
+
const props2 = {
|
|
3459
|
+
...additionalProperties,
|
|
3460
|
+
...eventMessage.properties || {},
|
|
3461
|
+
$groups: eventMessage.groups || groups
|
|
3462
|
+
};
|
|
3463
|
+
return props2;
|
|
3464
|
+
});
|
|
3465
|
+
if ("$pageview" === eventMessage.event && this.options.__preview_capture_bot_pageviews && "string" == typeof eventProperties.$raw_user_agent) {
|
|
3466
|
+
if (isBlockedUA(eventProperties.$raw_user_agent, this.options.custom_blocked_useragents || [])) {
|
|
3467
|
+
eventMessage.event = "$bot_pageview";
|
|
3468
|
+
eventProperties.$browser_type = "bot";
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
return {
|
|
3472
|
+
distinctId: eventMessage.distinctId,
|
|
3473
|
+
event: eventMessage.event,
|
|
3474
|
+
properties: eventProperties,
|
|
3475
|
+
options: {
|
|
3476
|
+
timestamp: eventMessage.timestamp,
|
|
3477
|
+
disableGeoip: eventMessage.disableGeoip,
|
|
3478
|
+
uuid: eventMessage.uuid
|
|
3479
|
+
}
|
|
3480
|
+
};
|
|
3481
|
+
}
|
|
3482
|
+
_runBeforeSend(eventMessage) {
|
|
3483
|
+
const beforeSend = this.options.before_send;
|
|
3484
|
+
if (!beforeSend) return eventMessage;
|
|
3485
|
+
const fns = Array.isArray(beforeSend) ? beforeSend : [
|
|
3486
|
+
beforeSend
|
|
3487
|
+
];
|
|
3488
|
+
let result = eventMessage;
|
|
3489
|
+
for (const fn of fns) {
|
|
3490
|
+
result = fn(result);
|
|
3491
|
+
if (!result) {
|
|
3492
|
+
this._logger.info(`Event '${eventMessage.event}' was rejected in beforeSend function`);
|
|
3493
|
+
return null;
|
|
3494
|
+
}
|
|
3495
|
+
if (!result.properties || 0 === Object.keys(result.properties).length) {
|
|
3496
|
+
const message = `Event '${result.event}' has no properties after beforeSend function, this is likely an error.`;
|
|
3497
|
+
this._logger.warn(message);
|
|
3498
|
+
}
|
|
3499
|
+
}
|
|
3500
|
+
return result;
|
|
3501
|
+
}
|
|
3502
|
+
};
|
|
3503
|
+
}
|
|
3504
|
+
});
|
|
3505
|
+
|
|
3506
|
+
// ../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/sentry-integration.mjs
|
|
3507
|
+
function createEventProcessor(_posthog, { organization, projectId, prefix, severityAllowList = [
|
|
3508
|
+
"error"
|
|
3509
|
+
], sendExceptionsToPostHog = true } = {}) {
|
|
3510
|
+
return (event) => {
|
|
3511
|
+
const shouldProcessLevel = "*" === severityAllowList || severityAllowList.includes(event.level);
|
|
3512
|
+
if (!shouldProcessLevel) return event;
|
|
3513
|
+
if (!event.tags) event.tags = {};
|
|
3514
|
+
const userId = event.tags[PostHogSentryIntegration.POSTHOG_ID_TAG];
|
|
3515
|
+
if (void 0 === userId) return event;
|
|
3516
|
+
const uiHost = _posthog.options.host ?? "https://us.i.posthog.com";
|
|
3517
|
+
const personUrl = new URL(`/project/${_posthog.apiKey}/person/${userId}`, uiHost).toString();
|
|
3518
|
+
event.tags["PostHog Person URL"] = personUrl;
|
|
3519
|
+
const exceptions = event.exception?.values || [];
|
|
3520
|
+
const exceptionList = exceptions.map((exception) => ({
|
|
3521
|
+
...exception,
|
|
3522
|
+
stacktrace: exception.stacktrace ? {
|
|
3523
|
+
...exception.stacktrace,
|
|
3524
|
+
type: "raw",
|
|
3525
|
+
frames: (exception.stacktrace.frames || []).map((frame) => ({
|
|
3526
|
+
...frame,
|
|
3527
|
+
platform: "node:javascript"
|
|
3528
|
+
}))
|
|
3529
|
+
} : void 0
|
|
3530
|
+
}));
|
|
3531
|
+
const properties = {
|
|
3532
|
+
$exception_message: exceptions[0]?.value || event.message,
|
|
3533
|
+
$exception_type: exceptions[0]?.type,
|
|
3534
|
+
$exception_level: event.level,
|
|
3535
|
+
$exception_list: exceptionList,
|
|
3536
|
+
$sentry_event_id: event.event_id,
|
|
3537
|
+
$sentry_exception: event.exception,
|
|
3538
|
+
$sentry_exception_message: exceptions[0]?.value || event.message,
|
|
3539
|
+
$sentry_exception_type: exceptions[0]?.type,
|
|
3540
|
+
$sentry_tags: event.tags
|
|
3541
|
+
};
|
|
3542
|
+
if (organization && projectId) properties["$sentry_url"] = (prefix || "https://sentry.io/organizations/") + organization + "/issues/?project=" + projectId + "&query=" + event.event_id;
|
|
3543
|
+
if (sendExceptionsToPostHog) _posthog.capture({
|
|
3544
|
+
event: "$exception",
|
|
3545
|
+
distinctId: userId,
|
|
3546
|
+
properties
|
|
3547
|
+
});
|
|
3548
|
+
return event;
|
|
3549
|
+
};
|
|
3550
|
+
}
|
|
3551
|
+
function sentryIntegration(_posthog, options) {
|
|
3552
|
+
const processor = createEventProcessor(_posthog, options);
|
|
3553
|
+
return {
|
|
3554
|
+
name: NAME,
|
|
3555
|
+
processEvent(event) {
|
|
3556
|
+
return processor(event);
|
|
3557
|
+
}
|
|
3558
|
+
};
|
|
3559
|
+
}
|
|
3560
|
+
var NAME, PostHogSentryIntegration;
|
|
3561
|
+
var init_sentry_integration = __esm({
|
|
3562
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/sentry-integration.mjs"() {
|
|
3563
|
+
NAME = "posthog-node";
|
|
3564
|
+
PostHogSentryIntegration = class {
|
|
3565
|
+
static #_ = this.POSTHOG_ID_TAG = "posthog_distinct_id";
|
|
3566
|
+
constructor(_posthog, organization, prefix, severityAllowList, sendExceptionsToPostHog) {
|
|
3567
|
+
this.name = NAME;
|
|
3568
|
+
this.name = NAME;
|
|
3569
|
+
this.setupOnce = function(addGlobalEventProcessor, getCurrentHub) {
|
|
3570
|
+
const projectId = getCurrentHub()?.getClient()?.getDsn()?.projectId;
|
|
3571
|
+
addGlobalEventProcessor(createEventProcessor(_posthog, {
|
|
3572
|
+
organization,
|
|
3573
|
+
projectId,
|
|
3574
|
+
prefix,
|
|
3575
|
+
severityAllowList,
|
|
3576
|
+
sendExceptionsToPostHog: sendExceptionsToPostHog ?? true
|
|
3577
|
+
}));
|
|
3578
|
+
};
|
|
3579
|
+
}
|
|
3580
|
+
};
|
|
3581
|
+
}
|
|
3582
|
+
});
|
|
3583
|
+
|
|
3584
|
+
// ../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/express.mjs
|
|
3585
|
+
function setupExpressErrorHandler(_posthog, app) {
|
|
3586
|
+
app.use((error, _, __, next) => {
|
|
3587
|
+
const hint = {
|
|
3588
|
+
mechanism: {
|
|
3589
|
+
type: "middleware",
|
|
3590
|
+
handled: false
|
|
3591
|
+
}
|
|
3592
|
+
};
|
|
3593
|
+
ErrorTracking.buildEventMessage(error, hint, uuidv7(), {
|
|
3594
|
+
$process_person_profile: false
|
|
3595
|
+
}).then((msg) => _posthog.capture(msg));
|
|
3596
|
+
next(error);
|
|
3597
|
+
});
|
|
3598
|
+
}
|
|
3599
|
+
var init_express = __esm({
|
|
3600
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/extensions/express.mjs"() {
|
|
3601
|
+
init_dist();
|
|
3602
|
+
init_error_tracking2();
|
|
3603
|
+
}
|
|
3604
|
+
});
|
|
3605
|
+
|
|
3606
|
+
// ../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/types.mjs
|
|
3607
|
+
var init_types3 = __esm({
|
|
3608
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/types.mjs"() {
|
|
3609
|
+
}
|
|
3610
|
+
});
|
|
3611
|
+
|
|
3612
|
+
// ../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/exports.mjs
|
|
3613
|
+
var init_exports = __esm({
|
|
3614
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/exports.mjs"() {
|
|
3615
|
+
init_sentry_integration();
|
|
3616
|
+
init_express();
|
|
3617
|
+
init_types3();
|
|
3618
|
+
}
|
|
3619
|
+
});
|
|
3620
|
+
|
|
3621
|
+
// ../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/entrypoints/index.node.mjs
|
|
3622
|
+
var index_node_exports = {};
|
|
3623
|
+
__export(index_node_exports, {
|
|
3624
|
+
PostHog: () => PostHog,
|
|
3625
|
+
PostHogSentryIntegration: () => PostHogSentryIntegration,
|
|
3626
|
+
createEventProcessor: () => createEventProcessor,
|
|
3627
|
+
sentryIntegration: () => sentryIntegration,
|
|
3628
|
+
setupExpressErrorHandler: () => setupExpressErrorHandler
|
|
3629
|
+
});
|
|
3630
|
+
var PostHog;
|
|
3631
|
+
var init_index_node = __esm({
|
|
3632
|
+
"../../node_modules/.pnpm/posthog-node@5.14.0/node_modules/posthog-node/dist/entrypoints/index.node.mjs"() {
|
|
3633
|
+
init_module_node();
|
|
3634
|
+
init_context_lines_node();
|
|
3635
|
+
init_error_tracking2();
|
|
3636
|
+
init_client();
|
|
3637
|
+
init_dist();
|
|
3638
|
+
init_exports();
|
|
3639
|
+
ErrorTracking.errorPropertiesBuilder = new error_tracking_exports.ErrorPropertiesBuilder([
|
|
3640
|
+
new error_tracking_exports.EventCoercer(),
|
|
3641
|
+
new error_tracking_exports.ErrorCoercer(),
|
|
3642
|
+
new error_tracking_exports.ObjectCoercer(),
|
|
3643
|
+
new error_tracking_exports.StringCoercer(),
|
|
3644
|
+
new error_tracking_exports.PrimitiveCoercer()
|
|
3645
|
+
], error_tracking_exports.createStackParser("node:javascript", error_tracking_exports.nodeStackLineParser), [
|
|
3646
|
+
createModulerModifier(),
|
|
3647
|
+
addSourceContext
|
|
3648
|
+
]);
|
|
3649
|
+
PostHog = class extends PostHogBackendClient {
|
|
3650
|
+
getLibraryId() {
|
|
3651
|
+
return "posthog-node";
|
|
3652
|
+
}
|
|
3653
|
+
};
|
|
3654
|
+
}
|
|
3655
|
+
});
|
|
3656
|
+
|
|
3657
|
+
// src/event-subscriber-base.ts
|
|
3658
|
+
var EventSubscriber = class {
|
|
3659
|
+
/**
|
|
3660
|
+
* Subscriber version (optional)
|
|
3661
|
+
*/
|
|
3662
|
+
version;
|
|
3663
|
+
/**
|
|
3664
|
+
* Enable/disable the subscriber (default: true)
|
|
3665
|
+
*/
|
|
3666
|
+
enabled = true;
|
|
3667
|
+
/**
|
|
3668
|
+
* Track pending requests for graceful shutdown
|
|
3669
|
+
*/
|
|
3670
|
+
pendingRequests = /* @__PURE__ */ new Set();
|
|
3671
|
+
/**
|
|
3672
|
+
* Optional: Handle errors
|
|
3673
|
+
*
|
|
3674
|
+
* Override this to customize error handling (logging, retries, etc.).
|
|
3675
|
+
* Default behavior: log to console.error
|
|
3676
|
+
*
|
|
3677
|
+
* @param error - Error that occurred
|
|
3678
|
+
* @param payload - Event payload that failed
|
|
3679
|
+
*/
|
|
3680
|
+
handleError(error, payload) {
|
|
3681
|
+
console.error(
|
|
3682
|
+
`[${this.name}] Failed to send ${payload.type}:`,
|
|
3683
|
+
error,
|
|
3684
|
+
payload
|
|
3685
|
+
);
|
|
3686
|
+
}
|
|
3687
|
+
/**
|
|
3688
|
+
* Track an event
|
|
3689
|
+
*/
|
|
3690
|
+
async trackEvent(name, attributes) {
|
|
3691
|
+
if (!this.enabled) return;
|
|
3692
|
+
const payload = {
|
|
3693
|
+
type: "event",
|
|
3694
|
+
name,
|
|
3695
|
+
attributes,
|
|
3696
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
3697
|
+
};
|
|
3698
|
+
await this.send(payload);
|
|
3699
|
+
}
|
|
3700
|
+
/**
|
|
3701
|
+
* Track a funnel step
|
|
3702
|
+
*/
|
|
3703
|
+
async trackFunnelStep(funnelName, step, attributes) {
|
|
3704
|
+
if (!this.enabled) return;
|
|
3705
|
+
const payload = {
|
|
3706
|
+
type: "funnel",
|
|
3707
|
+
name: `${funnelName}.${step}`,
|
|
3708
|
+
funnel: funnelName,
|
|
3709
|
+
step,
|
|
3710
|
+
attributes,
|
|
3711
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
3712
|
+
};
|
|
3713
|
+
await this.send(payload);
|
|
3714
|
+
}
|
|
3715
|
+
/**
|
|
3716
|
+
* Track an outcome
|
|
3717
|
+
*/
|
|
3718
|
+
async trackOutcome(operationName, outcome, attributes) {
|
|
3719
|
+
if (!this.enabled) return;
|
|
3720
|
+
const payload = {
|
|
3721
|
+
type: "outcome",
|
|
3722
|
+
name: `${operationName}.${outcome}`,
|
|
3723
|
+
operation: operationName,
|
|
3724
|
+
outcome,
|
|
3725
|
+
attributes,
|
|
3726
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
3727
|
+
};
|
|
3728
|
+
await this.send(payload);
|
|
3729
|
+
}
|
|
3730
|
+
/**
|
|
3731
|
+
* Track a value/metric
|
|
3732
|
+
*/
|
|
3733
|
+
async trackValue(name, value, attributes) {
|
|
3734
|
+
if (!this.enabled) return;
|
|
3735
|
+
const payload = {
|
|
3736
|
+
type: "value",
|
|
3737
|
+
name,
|
|
3738
|
+
value,
|
|
3739
|
+
attributes,
|
|
3740
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
3741
|
+
};
|
|
3742
|
+
await this.send(payload);
|
|
3743
|
+
}
|
|
3744
|
+
/**
|
|
3745
|
+
* Flush pending requests and clean up
|
|
3746
|
+
*
|
|
3747
|
+
* CRITICAL: Prevents race condition during shutdown
|
|
3748
|
+
* 1. Disables subscriber to stop new events
|
|
3749
|
+
* 2. Drains all pending requests (with retry logic)
|
|
3750
|
+
* 3. Ensures flush guarantee
|
|
3751
|
+
*
|
|
3752
|
+
* Override this if you need custom cleanup logic (close connections, flush buffers, etc.),
|
|
3753
|
+
* but ALWAYS call super.shutdown() first to drain pending requests.
|
|
3754
|
+
*/
|
|
3755
|
+
async shutdown() {
|
|
3756
|
+
this.enabled = false;
|
|
3757
|
+
const maxDrainAttempts = 10;
|
|
3758
|
+
const drainIntervalMs = 50;
|
|
3759
|
+
for (let attempt = 0; attempt < maxDrainAttempts; attempt++) {
|
|
3760
|
+
if (this.pendingRequests.size === 0) {
|
|
3761
|
+
break;
|
|
3762
|
+
}
|
|
3763
|
+
await Promise.allSettled(this.pendingRequests);
|
|
3764
|
+
if (this.pendingRequests.size > 0 && attempt < maxDrainAttempts - 1) {
|
|
3765
|
+
await new Promise((resolve) => setTimeout(resolve, drainIntervalMs));
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3768
|
+
if (this.pendingRequests.size > 0) {
|
|
3769
|
+
console.warn(
|
|
3770
|
+
`[${this.name}] Shutdown completed with ${this.pendingRequests.size} pending requests still in-flight. This may indicate a bug in the subscriber or extremely slow destination.`
|
|
3771
|
+
);
|
|
3772
|
+
}
|
|
3773
|
+
}
|
|
3774
|
+
/**
|
|
3775
|
+
* Internal: Send payload and track request
|
|
3776
|
+
*/
|
|
3777
|
+
async send(payload) {
|
|
3778
|
+
const request = this.sendWithErrorHandling(payload);
|
|
3779
|
+
this.pendingRequests.add(request);
|
|
3780
|
+
void request.finally(() => {
|
|
3781
|
+
this.pendingRequests.delete(request);
|
|
3782
|
+
});
|
|
3783
|
+
return request;
|
|
3784
|
+
}
|
|
3785
|
+
/**
|
|
3786
|
+
* Internal: Send with error handling
|
|
3787
|
+
*/
|
|
3788
|
+
async sendWithErrorHandling(payload) {
|
|
3789
|
+
try {
|
|
3790
|
+
await this.sendToDestination(payload);
|
|
3791
|
+
} catch (error) {
|
|
3792
|
+
this.handleError(error, payload);
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
};
|
|
3796
|
+
|
|
3797
|
+
// src/posthog.ts
|
|
3798
|
+
var PostHogSubscriber = class extends EventSubscriber {
|
|
3799
|
+
name = "PostHogSubscriber";
|
|
3800
|
+
version = "2.0.0";
|
|
3801
|
+
posthog = null;
|
|
3802
|
+
config;
|
|
3803
|
+
initPromise = null;
|
|
3804
|
+
constructor(config) {
|
|
3805
|
+
super();
|
|
3806
|
+
if (!config.apiKey && !config.client) {
|
|
3807
|
+
throw new Error("PostHogSubscriber requires either apiKey or client to be provided");
|
|
3808
|
+
}
|
|
3809
|
+
this.enabled = config.enabled ?? true;
|
|
3810
|
+
this.config = config;
|
|
3811
|
+
if (this.enabled) {
|
|
3812
|
+
this.initPromise = this.initialize();
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
3815
|
+
async initialize() {
|
|
3816
|
+
try {
|
|
3817
|
+
if (this.config.client) {
|
|
3818
|
+
this.posthog = this.config.client;
|
|
3819
|
+
this.setupErrorHandling();
|
|
3820
|
+
return;
|
|
3821
|
+
}
|
|
3822
|
+
const { PostHog: PostHog2 } = await Promise.resolve().then(() => (init_index_node(), index_node_exports));
|
|
3823
|
+
this.posthog = new PostHog2(this.config.apiKey, {
|
|
3824
|
+
host: this.config.host || "https://us.i.posthog.com",
|
|
3825
|
+
flushAt: this.config.flushAt,
|
|
3826
|
+
flushInterval: this.config.flushInterval,
|
|
3827
|
+
requestTimeout: this.config.requestTimeout,
|
|
3828
|
+
disableGeoip: this.config.disableGeoip,
|
|
3829
|
+
sendFeatureFlagEvent: this.config.sendFeatureFlags
|
|
3830
|
+
});
|
|
3831
|
+
this.setupErrorHandling();
|
|
3832
|
+
} catch (error) {
|
|
3833
|
+
console.error(
|
|
3834
|
+
"PostHog subscriber failed to initialize. Install posthog-node: pnpm add posthog-node",
|
|
3835
|
+
error
|
|
3836
|
+
);
|
|
3837
|
+
this.enabled = false;
|
|
3838
|
+
this.config.onError?.(error);
|
|
3839
|
+
}
|
|
3840
|
+
}
|
|
3841
|
+
setupErrorHandling() {
|
|
3842
|
+
if (this.config.debug) {
|
|
3843
|
+
this.posthog?.debug();
|
|
3844
|
+
}
|
|
3845
|
+
if (this.config.onError && this.posthog?.on) {
|
|
3846
|
+
this.posthog.on("error", this.config.onError);
|
|
3847
|
+
}
|
|
3848
|
+
}
|
|
3849
|
+
async ensureInitialized() {
|
|
3850
|
+
if (this.initPromise) {
|
|
3851
|
+
await this.initPromise;
|
|
3852
|
+
this.initPromise = null;
|
|
3853
|
+
}
|
|
3854
|
+
}
|
|
3855
|
+
extractDistinctId(attributes) {
|
|
3856
|
+
return attributes?.userId || attributes?.user_id || "anonymous";
|
|
3857
|
+
}
|
|
3858
|
+
/**
|
|
3859
|
+
* Send payload to PostHog
|
|
3860
|
+
*/
|
|
3861
|
+
async sendToDestination(payload) {
|
|
3862
|
+
await this.ensureInitialized();
|
|
3863
|
+
let properties = payload.attributes;
|
|
3864
|
+
if (payload.value !== void 0) {
|
|
3865
|
+
properties = { ...payload.attributes, value: payload.value };
|
|
3866
|
+
}
|
|
3867
|
+
const capturePayload = {
|
|
3868
|
+
distinctId: this.extractDistinctId(payload.attributes),
|
|
3869
|
+
event: payload.name,
|
|
3870
|
+
properties
|
|
3871
|
+
};
|
|
3872
|
+
if (payload.attributes?.groups) {
|
|
3873
|
+
capturePayload.groups = payload.attributes.groups;
|
|
3874
|
+
}
|
|
3875
|
+
this.posthog?.capture(capturePayload);
|
|
3876
|
+
}
|
|
3877
|
+
// Feature Flag Methods
|
|
3878
|
+
/**
|
|
3879
|
+
* Check if a feature flag is enabled for a user
|
|
3880
|
+
*
|
|
3881
|
+
* @param flagKey - Feature flag key
|
|
3882
|
+
* @param distinctId - User ID or anonymous ID
|
|
3883
|
+
* @param options - Feature flag evaluation options
|
|
3884
|
+
* @returns true if enabled, false otherwise
|
|
3885
|
+
*
|
|
3886
|
+
* @example
|
|
3887
|
+
* ```typescript
|
|
3888
|
+
* const isEnabled = await subscriber.isFeatureEnabled('new-checkout', 'user-123');
|
|
3889
|
+
*
|
|
3890
|
+
* // With groups
|
|
3891
|
+
* const isEnabled = await subscriber.isFeatureEnabled('beta-features', 'user-123', {
|
|
3892
|
+
* groups: { company: 'acme-corp' }
|
|
3893
|
+
* });
|
|
3894
|
+
* ```
|
|
3895
|
+
*/
|
|
3896
|
+
async isFeatureEnabled(flagKey, distinctId, options) {
|
|
3897
|
+
if (!this.enabled) return false;
|
|
3898
|
+
await this.ensureInitialized();
|
|
3899
|
+
try {
|
|
3900
|
+
return await this.posthog?.isFeatureEnabled(flagKey, distinctId, options) ?? false;
|
|
3901
|
+
} catch (error) {
|
|
3902
|
+
this.config.onError?.(error);
|
|
3903
|
+
return false;
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
/**
|
|
3907
|
+
* Get feature flag value for a user
|
|
3908
|
+
*
|
|
3909
|
+
* @param flagKey - Feature flag key
|
|
3910
|
+
* @param distinctId - User ID or anonymous ID
|
|
3911
|
+
* @param options - Feature flag evaluation options
|
|
3912
|
+
* @returns Flag value (string, boolean, or undefined)
|
|
3913
|
+
*
|
|
3914
|
+
* @example
|
|
3915
|
+
* ```typescript
|
|
3916
|
+
* const variant = await subscriber.getFeatureFlag('experiment-variant', 'user-123');
|
|
3917
|
+
* // Returns: 'control' | 'test' | 'test-2' | undefined
|
|
3918
|
+
*
|
|
3919
|
+
* // With person properties
|
|
3920
|
+
* const variant = await subscriber.getFeatureFlag('premium-feature', 'user-123', {
|
|
3921
|
+
* personProperties: { plan: 'premium' }
|
|
3922
|
+
* });
|
|
3923
|
+
* ```
|
|
3924
|
+
*/
|
|
3925
|
+
async getFeatureFlag(flagKey, distinctId, options) {
|
|
3926
|
+
if (!this.enabled) return void 0;
|
|
3927
|
+
await this.ensureInitialized();
|
|
3928
|
+
try {
|
|
3929
|
+
return await this.posthog?.getFeatureFlag(flagKey, distinctId, options);
|
|
3930
|
+
} catch (error) {
|
|
3931
|
+
this.config.onError?.(error);
|
|
3932
|
+
return void 0;
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3935
|
+
/**
|
|
3936
|
+
* Get all feature flags for a user
|
|
3937
|
+
*
|
|
3938
|
+
* @param distinctId - User ID or anonymous ID
|
|
3939
|
+
* @param options - Feature flag evaluation options
|
|
3940
|
+
* @returns Object mapping flag keys to their values
|
|
3941
|
+
*
|
|
3942
|
+
* @example
|
|
3943
|
+
* ```typescript
|
|
3944
|
+
* const flags = await subscriber.getAllFlags('user-123');
|
|
3945
|
+
* // Returns: { 'new-checkout': true, 'experiment-variant': 'test', ... }
|
|
3946
|
+
* ```
|
|
3947
|
+
*/
|
|
3948
|
+
async getAllFlags(distinctId, options) {
|
|
3949
|
+
if (!this.enabled) return {};
|
|
3950
|
+
await this.ensureInitialized();
|
|
3951
|
+
try {
|
|
3952
|
+
const flags = await this.posthog?.getAllFlags(distinctId, options);
|
|
3953
|
+
return flags ?? {};
|
|
3954
|
+
} catch (error) {
|
|
3955
|
+
this.config.onError?.(error);
|
|
3956
|
+
return {};
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
/**
|
|
3960
|
+
* Reload feature flags from PostHog server
|
|
3961
|
+
*
|
|
3962
|
+
* Call this to refresh feature flag definitions without restarting.
|
|
3963
|
+
*
|
|
3964
|
+
* @example
|
|
3965
|
+
* ```typescript
|
|
3966
|
+
* await subscriber.reloadFeatureFlags();
|
|
3967
|
+
* ```
|
|
3968
|
+
*/
|
|
3969
|
+
async reloadFeatureFlags() {
|
|
3970
|
+
if (!this.enabled) return;
|
|
3971
|
+
await this.ensureInitialized();
|
|
3972
|
+
try {
|
|
3973
|
+
await this.posthog?.reloadFeatureFlags();
|
|
3974
|
+
} catch (error) {
|
|
3975
|
+
this.config.onError?.(error);
|
|
3976
|
+
}
|
|
3977
|
+
}
|
|
3978
|
+
// Person and Group Events
|
|
3979
|
+
/**
|
|
3980
|
+
* Identify a user and set their properties
|
|
3981
|
+
*
|
|
3982
|
+
* @param distinctId - User ID
|
|
3983
|
+
* @param properties - Person properties ($set, $set_once, or custom properties)
|
|
3984
|
+
*
|
|
3985
|
+
* @example
|
|
3986
|
+
* ```typescript
|
|
3987
|
+
* // Set properties (will update existing values)
|
|
3988
|
+
* await subscriber.identify('user-123', {
|
|
3989
|
+
* $set: {
|
|
3990
|
+
* email: 'user@example.com',
|
|
3991
|
+
* plan: 'premium'
|
|
3992
|
+
* }
|
|
3993
|
+
* });
|
|
3994
|
+
*
|
|
3995
|
+
* // Set properties only once (won't update if already exists)
|
|
3996
|
+
* await subscriber.identify('user-123', {
|
|
3997
|
+
* $set_once: {
|
|
3998
|
+
* signup_date: '2025-01-17'
|
|
3999
|
+
* }
|
|
4000
|
+
* });
|
|
4001
|
+
* ```
|
|
4002
|
+
*/
|
|
4003
|
+
async identify(distinctId, properties) {
|
|
4004
|
+
if (!this.enabled) return;
|
|
4005
|
+
await this.ensureInitialized();
|
|
4006
|
+
try {
|
|
4007
|
+
this.posthog?.identify({
|
|
4008
|
+
distinctId,
|
|
4009
|
+
properties
|
|
4010
|
+
});
|
|
4011
|
+
} catch (error) {
|
|
4012
|
+
this.config.onError?.(error);
|
|
4013
|
+
}
|
|
4014
|
+
}
|
|
4015
|
+
/**
|
|
4016
|
+
* Identify a group and set its properties
|
|
4017
|
+
*
|
|
4018
|
+
* Groups are useful for B2B SaaS to track organizations, teams, or accounts.
|
|
4019
|
+
*
|
|
4020
|
+
* @param groupType - Type of group (e.g., 'company', 'organization', 'team')
|
|
4021
|
+
* @param groupKey - Unique identifier for the group
|
|
4022
|
+
* @param properties - Group properties
|
|
4023
|
+
*
|
|
4024
|
+
* @example
|
|
4025
|
+
* ```typescript
|
|
4026
|
+
* await subscriber.groupIdentify('company', 'acme-corp', {
|
|
4027
|
+
* $set: {
|
|
4028
|
+
* name: 'Acme Corporation',
|
|
4029
|
+
* industry: 'saas',
|
|
4030
|
+
* employees: 500,
|
|
4031
|
+
* plan: 'enterprise'
|
|
4032
|
+
* }
|
|
4033
|
+
* });
|
|
4034
|
+
* ```
|
|
4035
|
+
*/
|
|
4036
|
+
async groupIdentify(groupType, groupKey, properties) {
|
|
4037
|
+
if (!this.enabled) return;
|
|
4038
|
+
await this.ensureInitialized();
|
|
4039
|
+
try {
|
|
4040
|
+
this.posthog?.groupIdentify({
|
|
4041
|
+
groupType,
|
|
4042
|
+
groupKey: String(groupKey),
|
|
4043
|
+
// Convert to string for PostHog SDK
|
|
4044
|
+
properties
|
|
4045
|
+
});
|
|
4046
|
+
} catch (error) {
|
|
4047
|
+
this.config.onError?.(error);
|
|
4048
|
+
}
|
|
4049
|
+
}
|
|
4050
|
+
/**
|
|
4051
|
+
* Track an event with group context
|
|
4052
|
+
*
|
|
4053
|
+
* Use this to associate events with groups (e.g., organizations).
|
|
4054
|
+
*
|
|
4055
|
+
* @param name - Event name
|
|
4056
|
+
* @param attributes - Event attributes
|
|
4057
|
+
* @param groups - Group context (e.g., { company: 'acme-corp' })
|
|
4058
|
+
*
|
|
4059
|
+
* @example
|
|
4060
|
+
* ```typescript
|
|
4061
|
+
* await subscriber.trackEventWithGroups('feature.used', {
|
|
4062
|
+
* userId: 'user-123',
|
|
4063
|
+
* feature: 'advanced-events'
|
|
4064
|
+
* }, {
|
|
4065
|
+
* company: 'acme-corp'
|
|
4066
|
+
* });
|
|
4067
|
+
* ```
|
|
4068
|
+
*/
|
|
4069
|
+
async trackEventWithGroups(name, attributes, groups) {
|
|
4070
|
+
if (!this.enabled) return;
|
|
4071
|
+
await this.ensureInitialized();
|
|
4072
|
+
const eventAttributes = { ...attributes };
|
|
4073
|
+
if (groups) {
|
|
4074
|
+
eventAttributes.groups = groups;
|
|
4075
|
+
}
|
|
4076
|
+
await this.trackEvent(name, eventAttributes);
|
|
4077
|
+
}
|
|
4078
|
+
/**
|
|
4079
|
+
* Flush pending events and clean up resources
|
|
4080
|
+
*/
|
|
4081
|
+
async shutdown() {
|
|
4082
|
+
await super.shutdown();
|
|
4083
|
+
await this.ensureInitialized();
|
|
4084
|
+
if (this.posthog) {
|
|
4085
|
+
try {
|
|
4086
|
+
await this.posthog.shutdown();
|
|
4087
|
+
} catch (error) {
|
|
4088
|
+
this.config.onError?.(error);
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
4091
|
+
}
|
|
4092
|
+
/**
|
|
4093
|
+
* Handle errors with custom error handler
|
|
4094
|
+
*/
|
|
4095
|
+
handleError(error, payload) {
|
|
4096
|
+
this.config.onError?.(error);
|
|
4097
|
+
super.handleError(error, payload);
|
|
4098
|
+
}
|
|
4099
|
+
};
|
|
4100
|
+
/*! Bundled license information:
|
|
4101
|
+
|
|
4102
|
+
@posthog/core/dist/vendor/uuidv7.mjs:
|
|
4103
|
+
(*! For license information please see uuidv7.mjs.LICENSE.txt *)
|
|
4104
|
+
(**
|
|
4105
|
+
* uuidv7: An experimental implementation of the proposed UUID Version 7
|
|
4106
|
+
*
|
|
4107
|
+
* @license Apache-2.0
|
|
4108
|
+
* @copyright 2021-2023 LiosK
|
|
4109
|
+
* @packageDocumentation
|
|
4110
|
+
*)
|
|
4111
|
+
*/
|
|
4112
|
+
|
|
4113
|
+
exports.PostHogSubscriber = PostHogSubscriber;
|
|
4114
|
+
//# sourceMappingURL=posthog.cjs.map
|
|
4115
|
+
//# sourceMappingURL=posthog.cjs.map
|