@swmansion/argent 0.12.1 → 0.13.1-next.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/dist/cli-cmds.mjs CHANGED
@@ -171,12 +171,13 @@ import * as fs from "node:fs";
171
171
  import * as path from "node:path";
172
172
  import * as readline from "node:readline";
173
173
  import { homedir } from "node:os";
174
- import { spawn } from "node:child_process";
174
+ import { spawn, execFileSync } from "node:child_process";
175
175
  import { randomBytes } from "node:crypto";
176
176
  import { mkdir, writeFile, readFile, unlink, rename, chmod } from "node:fs/promises";
177
177
  var STATE_DIR = path.join(homedir(), ".argent");
178
178
  var STATE_FILE = path.join(STATE_DIR, "tool-server.json");
179
179
  var LOG_FILE = path.join(STATE_DIR, "tool-server.log");
180
+ var LOCK_FILE = path.join(STATE_DIR, "tool-server.lock");
180
181
  var AUTH_TOKEN_BYTES = 32;
181
182
  var AUTH_TOKEN_ENV = "ARGENT_AUTH_TOKEN";
182
183
  var AUTOSPAWN_IDLE_TIMEOUT_MINUTES = 30;
@@ -249,6 +250,8 @@ async function isToolsServerHealthy(port, host = "127.0.0.1", timeoutMs = 2e3, t
249
250
  signal: controller.signal,
250
251
  headers: authHeaders(token)
251
252
  });
253
+ await res.body?.cancel().catch(() => {
254
+ });
252
255
  return res.ok;
253
256
  } catch {
254
257
  return false;
@@ -256,6 +259,17 @@ async function isToolsServerHealthy(port, host = "127.0.0.1", timeoutMs = 2e3, t
256
259
  clearTimeout(timer);
257
260
  }
258
261
  }
262
+ var SPAWN_READY_TIMEOUT_MS = 15e3;
263
+ function killSpawnedChild(child, pid) {
264
+ try {
265
+ process.kill(-pid, "SIGKILL");
266
+ } catch {
267
+ try {
268
+ child.kill("SIGKILL");
269
+ } catch {
270
+ }
271
+ }
272
+ }
259
273
  function spawnToolsServer(paths, port, options = {}) {
260
274
  return new Promise((resolve3, reject) => {
261
275
  let logFd;
@@ -282,6 +296,10 @@ function spawnToolsServer(paths, port, options = {}) {
282
296
  settled = true;
283
297
  fn();
284
298
  };
299
+ const rejectAndKill = (err) => settle(() => {
300
+ killSpawnedChild(child, pid);
301
+ reject(err);
302
+ });
285
303
  const rl = readline.createInterface({ input: child.stdout });
286
304
  rl.on("line", (line) => {
287
305
  const match = line.match(/Tools server listening on http:\/\/.+:(\d+)/);
@@ -294,7 +312,7 @@ function spawnToolsServer(paths, port, options = {}) {
294
312
  });
295
313
  child.on("error", (err) => {
296
314
  rl.close();
297
- settle(() => reject(err));
315
+ rejectAndKill(err);
298
316
  });
299
317
  child.on("exit", (code) => {
300
318
  rl.close();
@@ -302,8 +320,8 @@ function spawnToolsServer(paths, port, options = {}) {
302
320
  });
303
321
  const timer = setTimeout(() => {
304
322
  rl.close();
305
- settle(() => reject(new Error("Timed out waiting for tools server to become ready")));
306
- }, 15e3);
323
+ rejectAndKill(new Error("Timed out waiting for tools server to become ready"));
324
+ }, options.readyTimeoutMs ?? SPAWN_READY_TIMEOUT_MS);
307
325
  rl.on("close", () => clearTimeout(timer));
308
326
  });
309
327
  }
@@ -359,63 +377,141 @@ async function waitForExit(pid, timeoutMs) {
359
377
  }
360
378
  return !isProcessAlive(pid);
361
379
  }
380
+ async function terminatePid(pid, stillOurs) {
381
+ if (!isProcessAlive(pid)) return;
382
+ if (stillOurs && !stillOurs()) return;
383
+ try {
384
+ process.kill(pid, "SIGTERM");
385
+ } catch {
386
+ return;
387
+ }
388
+ if (await waitForExit(pid, SIGTERM_GRACE_MS)) return;
389
+ if (stillOurs && !(isProcessAlive(pid) && stillOurs())) return;
390
+ try {
391
+ process.kill(pid, "SIGKILL");
392
+ } catch {
393
+ return;
394
+ }
395
+ await waitForExit(pid, SIGKILL_GRACE_MS);
396
+ }
362
397
  async function killToolServer() {
363
398
  const state2 = await readState();
364
399
  if (!state2) return;
365
- let exited = !isProcessAlive(state2.pid);
366
- if (!exited) {
400
+ await terminatePid(state2.pid);
401
+ await clearState();
402
+ }
403
+ function processCommandMatches(pid, marker) {
404
+ if (!marker) return false;
405
+ try {
406
+ const cmd = execFileSync("ps", ["-p", String(pid), "-o", "command="], {
407
+ encoding: "utf8",
408
+ timeout: 2e3,
409
+ stdio: ["ignore", "pipe", "ignore"]
410
+ }).trim();
411
+ if (!cmd) return false;
412
+ const argv = cmd.split(/\s+/);
413
+ return argv.includes(marker) && argv.includes("start");
414
+ } catch {
415
+ return false;
416
+ }
417
+ }
418
+ var LOCK_WAIT_TIMEOUT_MS = 3e4;
419
+ var LOCK_STALE_MS = 45e3;
420
+ var LOCK_POLL_MS = 100;
421
+ function spawnLockIsStale() {
422
+ try {
423
+ const { pid, ts } = JSON.parse(fs.readFileSync(LOCK_FILE, "utf8"));
424
+ if (typeof pid === "number" && pid > 0 && !isProcessAlive(pid)) return true;
425
+ if (typeof ts === "number" && Date.now() - ts > LOCK_STALE_MS) return true;
426
+ return false;
427
+ } catch {
367
428
  try {
368
- process.kill(state2.pid, "SIGTERM");
429
+ return Date.now() - fs.statSync(LOCK_FILE).mtimeMs > LOCK_STALE_MS;
369
430
  } catch {
370
- exited = true;
431
+ return true;
371
432
  }
372
433
  }
373
- if (!exited) {
374
- exited = await waitForExit(state2.pid, SIGTERM_GRACE_MS);
434
+ }
435
+ async function acquireSpawnLock() {
436
+ try {
437
+ fs.mkdirSync(STATE_DIR, { recursive: true });
438
+ } catch {
439
+ return null;
375
440
  }
376
- if (!exited) {
441
+ const nonce = randomBytes(8).toString("hex");
442
+ const deadline = Date.now() + LOCK_WAIT_TIMEOUT_MS;
443
+ for (; ; ) {
377
444
  try {
378
- process.kill(state2.pid, "SIGKILL");
379
- } catch {
380
- exited = true;
381
- }
382
- if (!exited) {
383
- await waitForExit(state2.pid, SIGKILL_GRACE_MS);
445
+ const fd = fs.openSync(LOCK_FILE, "wx");
446
+ try {
447
+ fs.writeSync(fd, JSON.stringify({ pid: process.pid, nonce, ts: Date.now() }));
448
+ } finally {
449
+ fs.closeSync(fd);
450
+ }
451
+ let released = false;
452
+ return {
453
+ release: () => {
454
+ if (released) return;
455
+ released = true;
456
+ try {
457
+ const cur = JSON.parse(fs.readFileSync(LOCK_FILE, "utf8"));
458
+ if (cur.pid === process.pid && cur.nonce === nonce) fs.unlinkSync(LOCK_FILE);
459
+ } catch {
460
+ }
461
+ }
462
+ };
463
+ } catch (err) {
464
+ if (err.code !== "EEXIST") return null;
465
+ if (spawnLockIsStale()) {
466
+ try {
467
+ fs.unlinkSync(LOCK_FILE);
468
+ } catch {
469
+ }
470
+ if (!fs.existsSync(LOCK_FILE)) continue;
471
+ }
472
+ if (Date.now() >= deadline) return null;
473
+ await new Promise((r2) => setTimeout(r2, LOCK_POLL_MS));
384
474
  }
385
475
  }
386
- await clearState();
476
+ }
477
+ async function reusableHandle(state2) {
478
+ if (!state2 || !isProcessAlive(state2.pid)) return null;
479
+ const host = state2.host ?? "127.0.0.1";
480
+ const healthy = await isToolsServerHealthy(state2.port, host, 2e3, state2.token);
481
+ if (!healthy) return null;
482
+ return { url: formatUrl(healthCheckHost(host), state2.port), token: state2.token ?? "" };
387
483
  }
388
484
  async function ensureToolsServer(paths) {
389
- const state2 = await readState();
390
- if (state2) {
391
- const alive = isProcessAlive(state2.pid);
392
- if (alive) {
393
- const host = state2.host ?? "127.0.0.1";
394
- const healthy = await isToolsServerHealthy(state2.port, host, 2e3, state2.token);
395
- if (healthy) {
396
- return {
397
- url: formatUrl(healthCheckHost(host), state2.port),
398
- token: state2.token ?? ""
399
- };
400
- }
485
+ const fast = await reusableHandle(await readState());
486
+ if (fast) return fast;
487
+ const lock = await acquireSpawnLock();
488
+ try {
489
+ const state2 = await readState();
490
+ const reuse = await reusableHandle(state2);
491
+ if (reuse) return reuse;
492
+ if (state2 && state2.managed === "autospawn" && isProcessAlive(state2.pid) && processCommandMatches(state2.pid, state2.bundlePath)) {
493
+ await terminatePid(state2.pid, () => processCommandMatches(state2.pid, state2.bundlePath));
401
494
  }
402
495
  await clearState();
496
+ const token = generateToken();
497
+ const port = await findFreePort();
498
+ const { port: actualPort, pid } = await spawnToolsServer(paths, port, {
499
+ token,
500
+ idleTimeoutMinutes: AUTOSPAWN_IDLE_TIMEOUT_MINUTES
501
+ });
502
+ await writeState({
503
+ port: actualPort,
504
+ pid,
505
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
506
+ bundlePath: paths.bundlePath,
507
+ host: "127.0.0.1",
508
+ token,
509
+ managed: "autospawn"
510
+ });
511
+ return { url: formatUrl("127.0.0.1", actualPort), token };
512
+ } finally {
513
+ lock?.release();
403
514
  }
404
- const token = generateToken();
405
- const port = await findFreePort();
406
- const { port: actualPort, pid } = await spawnToolsServer(paths, port, {
407
- token,
408
- idleTimeoutMinutes: AUTOSPAWN_IDLE_TIMEOUT_MINUTES
409
- });
410
- await writeState({
411
- port: actualPort,
412
- pid,
413
- startedAt: (/* @__PURE__ */ new Date()).toISOString(),
414
- bundlePath: paths.bundlePath,
415
- host: "127.0.0.1",
416
- token
417
- });
418
- return { url: formatUrl("127.0.0.1", actualPort), token };
419
515
  }
420
516
 
421
517
  // ../argent-tools-client/src/link-config.ts
@@ -933,6 +1029,7 @@ var types_PostHogPersistedProperty = /* @__PURE__ */ (function(PostHogPersistedP
933
1029
  PostHogPersistedProperty["InstalledAppBuild"] = "installed_app_build";
934
1030
  PostHogPersistedProperty["InstalledAppVersion"] = "installed_app_version";
935
1031
  PostHogPersistedProperty["SessionReplay"] = "session_replay";
1032
+ PostHogPersistedProperty["SessionReplayEventTriggerActivatedSession"] = "session_replay_event_trigger_activated_session";
936
1033
  PostHogPersistedProperty["SurveyLastSeenDate"] = "survey_last_seen_date";
937
1034
  PostHogPersistedProperty["SurveysSeen"] = "surveys_seen";
938
1035
  PostHogPersistedProperty["Surveys"] = "surveys";
@@ -1461,6 +1558,14 @@ var GENERIC_MOBILE = GENERIC + " " + MOBILE.toLowerCase();
1461
1558
  var GENERIC_TABLET = GENERIC + " " + TABLET.toLowerCase();
1462
1559
  var KONQUEROR = "Konqueror";
1463
1560
  var OCULUS_BROWSER = "Oculus Browser";
1561
+ var VIVALDI = "Vivaldi";
1562
+ var YANDEX = "Yandex";
1563
+ var WHALE = "Whale";
1564
+ var DUCKDUCKGO = "DuckDuckGo";
1565
+ var PALE_MOON = "Pale Moon";
1566
+ var WATERFOX = "Waterfox";
1567
+ var BRAVE = "Brave";
1568
+ var GOOGLE_SEARCH_APP = "Google Search App";
1464
1569
  var BROWSER_VERSION_REGEX_SUFFIX = "(\\d+(\\.\\d+)?)";
1465
1570
  var DEFAULT_BROWSER_VERSION_REGEX = new RegExp("Version/" + BROWSER_VERSION_REGEX_SUFFIX);
1466
1571
  var XBOX_REGEX = new RegExp(XBOX, "i");
@@ -1527,6 +1632,30 @@ var versionRegexes = {
1527
1632
  [OCULUS_BROWSER]: [
1528
1633
  new RegExp("OculusBrowser\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1529
1634
  ],
1635
+ [VIVALDI]: [
1636
+ new RegExp(VIVALDI + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1637
+ ],
1638
+ [YANDEX]: [
1639
+ new RegExp("YaBrowser\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1640
+ ],
1641
+ [WHALE]: [
1642
+ new RegExp(WHALE + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1643
+ ],
1644
+ [BRAVE]: [
1645
+ new RegExp(BRAVE + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1646
+ ],
1647
+ [DUCKDUCKGO]: [
1648
+ new RegExp("(DuckDuckGo|Ddg)\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1649
+ ],
1650
+ [PALE_MOON]: [
1651
+ new RegExp("PaleMoon\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1652
+ ],
1653
+ [WATERFOX]: [
1654
+ new RegExp(WATERFOX + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1655
+ ],
1656
+ [GOOGLE_SEARCH_APP]: [
1657
+ new RegExp("GSA\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1658
+ ],
1530
1659
  [INTERNET_EXPLORER]: [
1531
1660
  new RegExp("(rv:|MSIE )" + BROWSER_VERSION_REGEX_SUFFIX)
1532
1661
  ],
@@ -1684,6 +1813,13 @@ var osMatchers = [
1684
1813
 
1685
1814
  // ../../node_modules/@posthog/core/dist/utils/index.mjs
1686
1815
  var STRING_FORMAT = "utf8";
1816
+ var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1817
+ function isValidUUID(value) {
1818
+ return "string" == typeof value && UUID_REGEX.test(value);
1819
+ }
1820
+ function getEventUuid(uuid, generateUuid) {
1821
+ return isValidUUID(uuid) ? uuid : generateUuid();
1822
+ }
1687
1823
  function removeTrailingSlash(url) {
1688
1824
  return url?.replace(/\/+$/, "");
1689
1825
  }
@@ -1768,1515 +1904,1547 @@ var SimpleEventEmitter = class {
1768
1904
  }
1769
1905
  };
1770
1906
 
1771
- // ../../node_modules/@posthog/core/dist/posthog-core-stateless.mjs
1772
- var PostHogFetchHttpError = class extends Error {
1773
- constructor(response, reqByteLength) {
1774
- super("HTTP error while fetching PostHog: status=" + response.status + ", reqByteLength=" + reqByteLength), this.response = response, this.reqByteLength = reqByteLength, this.name = "PostHogFetchHttpError";
1775
- }
1776
- get status() {
1777
- return this.response.status;
1778
- }
1779
- get text() {
1780
- return this.response.text();
1781
- }
1782
- get json() {
1783
- return this.response.json();
1784
- }
1785
- };
1786
- var PostHogFetchNetworkError = class extends Error {
1787
- constructor(error) {
1788
- super("Network error while fetching PostHog", error instanceof Error ? {
1789
- cause: error
1790
- } : {}), this.error = error, this.name = "PostHogFetchNetworkError";
1791
- }
1792
- };
1793
- async function logFlushError(err) {
1794
- if (err instanceof PostHogFetchHttpError) {
1795
- let text2 = "";
1796
- try {
1797
- text2 = await err.text;
1798
- } catch {
1907
+ // ../../node_modules/@posthog/core/dist/error-tracking/index.mjs
1908
+ var error_tracking_exports = {};
1909
+ __export(error_tracking_exports, {
1910
+ DEFAULT_EXCEPTION_STEPS_CONFIG: () => DEFAULT_EXCEPTION_STEPS_CONFIG,
1911
+ DOMExceptionCoercer: () => DOMExceptionCoercer,
1912
+ EXCEPTION_STEP_INTERNAL_FIELDS: () => EXCEPTION_STEP_INTERNAL_FIELDS,
1913
+ ErrorCoercer: () => ErrorCoercer,
1914
+ ErrorEventCoercer: () => ErrorEventCoercer,
1915
+ ErrorPropertiesBuilder: () => ErrorPropertiesBuilder,
1916
+ EventCoercer: () => EventCoercer,
1917
+ ExceptionStepsBuffer: () => ExceptionStepsBuffer,
1918
+ ObjectCoercer: () => ObjectCoercer,
1919
+ PrimitiveCoercer: () => PrimitiveCoercer,
1920
+ PromiseRejectionEventCoercer: () => PromiseRejectionEventCoercer,
1921
+ ReduceableCache: () => ReduceableCache,
1922
+ StringCoercer: () => StringCoercer,
1923
+ chromeStackLineParser: () => chromeStackLineParser,
1924
+ createDefaultStackParser: () => createDefaultStackParser,
1925
+ createStackParser: () => createStackParser,
1926
+ geckoStackLineParser: () => geckoStackLineParser,
1927
+ getUtf8ByteLength: () => getUtf8ByteLength,
1928
+ nodeStackLineParser: () => nodeStackLineParser,
1929
+ opera10StackLineParser: () => opera10StackLineParser,
1930
+ opera11StackLineParser: () => opera11StackLineParser,
1931
+ resolveExceptionStepsConfig: () => resolveExceptionStepsConfig,
1932
+ reverseAndStripFrames: () => reverseAndStripFrames,
1933
+ stripReservedExceptionStepFields: () => stripReservedExceptionStepFields,
1934
+ winjsStackLineParser: () => winjsStackLineParser
1935
+ });
1936
+
1937
+ // ../../node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
1938
+ var parsedStackResults;
1939
+ var lastKeysCount;
1940
+ var cachedFilenameChunkIds;
1941
+ function getFilenameToChunkIdMap(stackParser) {
1942
+ const chunkIdMap = globalThis._posthogChunkIds;
1943
+ if (!chunkIdMap) return;
1944
+ const chunkIdKeys = Object.keys(chunkIdMap);
1945
+ if (cachedFilenameChunkIds && chunkIdKeys.length === lastKeysCount) return cachedFilenameChunkIds;
1946
+ lastKeysCount = chunkIdKeys.length;
1947
+ cachedFilenameChunkIds = chunkIdKeys.reduce((acc, stackKey) => {
1948
+ if (!parsedStackResults) parsedStackResults = {};
1949
+ const result = parsedStackResults[stackKey];
1950
+ if (result) acc[result[0]] = result[1];
1951
+ else {
1952
+ const parsedStack = stackParser(stackKey);
1953
+ for (let i2 = parsedStack.length - 1; i2 >= 0; i2--) {
1954
+ const stackFrame = parsedStack[i2];
1955
+ const filename = stackFrame?.filename;
1956
+ const chunkId = chunkIdMap[stackKey];
1957
+ if (filename && chunkId) {
1958
+ acc[filename] = chunkId;
1959
+ parsedStackResults[stackKey] = [
1960
+ filename,
1961
+ chunkId
1962
+ ];
1963
+ break;
1964
+ }
1965
+ }
1799
1966
  }
1800
- console.error(`Error while flushing PostHog: message=${err.message}, response body=${text2}`, err);
1801
- } else console.error("Error while flushing PostHog", err);
1802
- return Promise.resolve();
1803
- }
1804
- function isPostHogFetchError(err) {
1805
- return "object" == typeof err && (err instanceof PostHogFetchHttpError || err instanceof PostHogFetchNetworkError);
1806
- }
1807
- function isPostHogFetchContentTooLargeError(err) {
1808
- return "object" == typeof err && err instanceof PostHogFetchHttpError && 413 === err.status;
1967
+ return acc;
1968
+ }, {});
1969
+ return cachedFilenameChunkIds;
1809
1970
  }
1810
- var PostHogCoreStateless = class {
1811
- constructor(apiKey, options = {}) {
1812
- this.flushPromise = null;
1813
- this.shutdownPromise = null;
1814
- this.promiseQueue = new PromiseQueue();
1815
- this._events = new SimpleEventEmitter();
1816
- this._isInitialized = false;
1817
- const normalizedApiKey = "string" == typeof apiKey ? apiKey.trim() : "";
1818
- const normalizedHost = "string" == typeof options.host ? options.host.trim() : "";
1819
- const missingApiKey = !normalizedApiKey;
1820
- this._logger = createLogger("[PostHog]", this.logMsgIfDebug.bind(this));
1821
- if (missingApiKey) this._logger.error("You must pass your PostHog project's api key. The client will be disabled.");
1822
- this.apiKey = normalizedApiKey;
1823
- this.host = removeTrailingSlash(normalizedHost || "https://us.i.posthog.com");
1824
- this.flushAt = options.flushAt ? Math.max(options.flushAt, 1) : 20;
1825
- this.maxBatchSize = Math.max(this.flushAt, options.maxBatchSize ?? 100);
1826
- this.maxQueueSize = Math.max(this.flushAt, options.maxQueueSize ?? 1e3);
1827
- this.flushInterval = options.flushInterval ?? 1e4;
1828
- this.preloadFeatureFlags = options.preloadFeatureFlags ?? true;
1829
- this.defaultOptIn = options.defaultOptIn ?? true;
1830
- this.disableSurveys = options.disableSurveys ?? false;
1831
- this._retryOptions = {
1832
- retryCount: options.fetchRetryCount ?? 3,
1833
- retryDelay: options.fetchRetryDelay ?? 3e3,
1834
- retryCheck: isPostHogFetchError
1835
- };
1836
- this.requestTimeout = options.requestTimeout ?? 1e4;
1837
- this.featureFlagsRequestTimeoutMs = options.featureFlagsRequestTimeoutMs ?? 3e3;
1838
- this.remoteConfigRequestTimeoutMs = options.remoteConfigRequestTimeoutMs ?? 3e3;
1839
- this.disableGeoip = options.disableGeoip ?? true;
1840
- this.disabled = (options.disabled ?? false) || missingApiKey;
1841
- this.historicalMigration = options?.historicalMigration ?? false;
1842
- this._initPromise = Promise.resolve();
1843
- this._isInitialized = true;
1844
- this.evaluationContexts = options?.evaluationContexts ?? options?.evaluationEnvironments;
1845
- if (options?.evaluationEnvironments && !options?.evaluationContexts) this._logger.warn("evaluationEnvironments is deprecated. Use evaluationContexts instead. This property will be removed in a future version.");
1846
- this.disableCompression = !isGzipSupported() || (options?.disableCompression ?? false);
1971
+
1972
+ // ../../node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
1973
+ var MAX_CAUSE_RECURSION = 4;
1974
+ var ErrorPropertiesBuilder = class {
1975
+ constructor(coercers, stackParser, modifiers = []) {
1976
+ this.coercers = coercers;
1977
+ this.stackParser = stackParser;
1978
+ this.modifiers = modifiers;
1847
1979
  }
1848
- logMsgIfDebug(fn) {
1849
- if (this.isDebug) fn();
1980
+ buildFromUnknown(input, hint = {}) {
1981
+ const providedMechanism = hint && hint.mechanism;
1982
+ const mechanism = providedMechanism || {
1983
+ handled: true,
1984
+ type: "generic"
1985
+ };
1986
+ const coercingContext = this.buildCoercingContext(mechanism, hint, 0);
1987
+ const exceptionWithCause = coercingContext.apply(input);
1988
+ const parsingContext = this.buildParsingContext(hint);
1989
+ const exceptionWithStack = this.parseStacktrace(exceptionWithCause, parsingContext);
1990
+ const exceptionList = this.convertToExceptionList(exceptionWithStack, mechanism);
1991
+ return {
1992
+ $exception_list: exceptionList,
1993
+ $exception_level: "error"
1994
+ };
1850
1995
  }
1851
- wrap(fn) {
1852
- if (this.disabled) return void this._logger.warn("The client is disabled");
1853
- if (this._isInitialized) return fn();
1854
- this._initPromise.then(() => fn());
1996
+ async modifyFrames(exceptionList) {
1997
+ for (const exc of exceptionList) if (exc.stacktrace && exc.stacktrace.frames && isArray(exc.stacktrace.frames)) exc.stacktrace.frames = await this.applyModifiers(exc.stacktrace.frames);
1998
+ return exceptionList;
1855
1999
  }
1856
- getCommonEventProperties() {
2000
+ coerceFallback(ctx) {
1857
2001
  return {
1858
- $lib: this.getLibraryId(),
1859
- $lib_version: this.getLibraryVersion()
2002
+ type: "Error",
2003
+ value: "Unknown error",
2004
+ stack: ctx.syntheticException?.stack,
2005
+ synthetic: true
1860
2006
  };
1861
2007
  }
1862
- get optedOut() {
1863
- return this.getPersistedProperty(types_PostHogPersistedProperty.OptedOut) ?? !this.defaultOptIn;
1864
- }
1865
- async optIn() {
1866
- this.wrap(() => {
1867
- this.setPersistedProperty(types_PostHogPersistedProperty.OptedOut, false);
1868
- });
1869
- }
1870
- async optOut() {
1871
- this.wrap(() => {
1872
- this.setPersistedProperty(types_PostHogPersistedProperty.OptedOut, true);
1873
- });
1874
- }
1875
- on(event, cb) {
1876
- return this._events.on(event, cb);
1877
- }
1878
- debug(enabled = true) {
1879
- this.removeDebugCallback?.();
1880
- if (enabled) {
1881
- const removeDebugCallback = this.on("*", (event, payload) => this._logger.info(event, payload));
1882
- this.removeDebugCallback = () => {
1883
- removeDebugCallback();
1884
- this.removeDebugCallback = void 0;
1885
- };
1886
- }
1887
- }
1888
- get isDebug() {
1889
- return !!this.removeDebugCallback;
1890
- }
1891
- get isDisabled() {
1892
- return this.disabled;
1893
- }
1894
- buildPayload(payload) {
2008
+ parseStacktrace(err, ctx) {
2009
+ let cause;
2010
+ if (null != err.cause) cause = this.parseStacktrace(err.cause, ctx);
2011
+ let stack;
2012
+ if ("" != err.stack && null != err.stack) stack = this.applyChunkIds(this.stackParser(err.stack, err.synthetic ? ctx.skipFirstLines : 0), ctx.chunkIdMap);
1895
2013
  return {
1896
- distinct_id: payload.distinct_id,
1897
- event: payload.event,
1898
- properties: {
1899
- ...payload.properties || {},
1900
- ...this.getCommonEventProperties()
1901
- }
1902
- };
1903
- }
1904
- addPendingPromise(promise) {
1905
- return this.promiseQueue.add(promise);
1906
- }
1907
- identifyStateless(distinctId, properties, options) {
1908
- this.wrap(() => {
1909
- const payload = {
1910
- ...this.buildPayload({
1911
- distinct_id: distinctId,
1912
- event: "$identify",
1913
- properties
1914
- })
1915
- };
1916
- this.enqueue("identify", payload, options);
1917
- });
1918
- }
1919
- async identifyStatelessImmediate(distinctId, properties, options) {
1920
- const payload = {
1921
- ...this.buildPayload({
1922
- distinct_id: distinctId,
1923
- event: "$identify",
1924
- properties
1925
- })
2014
+ ...err,
2015
+ cause,
2016
+ stack
1926
2017
  };
1927
- await this.sendImmediate("identify", payload, options);
1928
- }
1929
- captureStateless(distinctId, event, properties, options) {
1930
- this.wrap(() => {
1931
- const payload = this.buildPayload({
1932
- distinct_id: distinctId,
1933
- event,
1934
- properties
1935
- });
1936
- this.enqueue("capture", payload, options);
1937
- });
1938
- }
1939
- async captureStatelessImmediate(distinctId, event, properties, options) {
1940
- const payload = this.buildPayload({
1941
- distinct_id: distinctId,
1942
- event,
1943
- properties
1944
- });
1945
- await this.sendImmediate("capture", payload, options);
1946
2018
  }
1947
- aliasStateless(alias, distinctId, properties, options) {
1948
- this.wrap(() => {
1949
- const payload = this.buildPayload({
1950
- event: "$create_alias",
1951
- distinct_id: distinctId,
1952
- properties: {
1953
- ...properties || {},
1954
- distinct_id: distinctId,
1955
- alias
1956
- }
1957
- });
1958
- this.enqueue("alias", payload, options);
2019
+ applyChunkIds(frames, chunkIdMap) {
2020
+ return frames.map((frame) => {
2021
+ if (frame.filename && chunkIdMap) frame.chunk_id = chunkIdMap[frame.filename];
2022
+ return frame;
1959
2023
  });
1960
2024
  }
1961
- async aliasStatelessImmediate(alias, distinctId, properties, options) {
1962
- const payload = this.buildPayload({
1963
- event: "$create_alias",
1964
- distinct_id: distinctId,
1965
- properties: {
1966
- ...properties || {},
1967
- distinct_id: distinctId,
1968
- alias
1969
- }
1970
- });
1971
- await this.sendImmediate("alias", payload, options);
2025
+ applyCoercers(input, ctx) {
2026
+ for (const adapter of this.coercers) if (adapter.match(input)) return adapter.coerce(input, ctx);
2027
+ return this.coerceFallback(ctx);
1972
2028
  }
1973
- groupIdentifyStateless(groupType, groupKey, groupProperties, options, distinctId, eventProperties) {
1974
- this.wrap(() => {
1975
- const payload = this.buildPayload({
1976
- distinct_id: distinctId || `$${groupType}_${groupKey}`,
1977
- event: "$groupidentify",
1978
- properties: {
1979
- $group_type: groupType,
1980
- $group_key: groupKey,
1981
- $group_set: groupProperties || {},
1982
- ...eventProperties || {}
1983
- }
1984
- });
1985
- this.enqueue("capture", payload, options);
1986
- });
2029
+ async applyModifiers(frames) {
2030
+ let newFrames = frames;
2031
+ for (const modifier of this.modifiers) newFrames = await modifier(newFrames);
2032
+ return newFrames;
1987
2033
  }
1988
- async getRemoteConfig() {
1989
- await this._initPromise;
1990
- let host = this.host;
1991
- if ("https://us.i.posthog.com" === host) host = "https://us-assets.i.posthog.com";
1992
- else if ("https://eu.i.posthog.com" === host) host = "https://eu-assets.i.posthog.com";
1993
- const url = `${host}/array/${this.apiKey}/config`;
1994
- const fetchOptions = {
1995
- method: "GET",
1996
- headers: {
1997
- ...this.getCustomHeaders(),
1998
- "Content-Type": "application/json"
2034
+ convertToExceptionList(exceptionWithStack, mechanism) {
2035
+ const currentException = {
2036
+ type: exceptionWithStack.type,
2037
+ value: exceptionWithStack.value,
2038
+ mechanism: {
2039
+ type: mechanism.type ?? "generic",
2040
+ handled: mechanism.handled ?? true,
2041
+ synthetic: exceptionWithStack.synthetic ?? false
1999
2042
  }
2000
2043
  };
2001
- return this.fetchWithRetry(url, fetchOptions, {
2002
- retryCount: 0
2003
- }, this.remoteConfigRequestTimeoutMs).then((response) => response.json()).catch((error) => {
2004
- this._logger.error("Remote config could not be loaded", error);
2005
- this._events.emit("error", error);
2006
- });
2007
- }
2008
- async getFlags(distinctId, groups = {}, personProperties = {}, groupProperties = {}, extraPayload = {}, fetchConfig = false) {
2009
- await this._initPromise;
2010
- const configParam = fetchConfig ? "&config=true" : "";
2011
- const url = `${this.host}/flags/?v=2${configParam}`;
2012
- const requestData = {
2013
- token: this.apiKey,
2014
- distinct_id: distinctId,
2015
- groups,
2016
- person_properties: personProperties,
2017
- group_properties: groupProperties,
2018
- ...extraPayload
2019
- };
2020
- if (personProperties.$device_id) requestData.$device_id = personProperties.$device_id;
2021
- if (this.evaluationContexts && this.evaluationContexts.length > 0) requestData.evaluation_contexts = this.evaluationContexts;
2022
- const fetchOptions = {
2023
- method: "POST",
2024
- headers: {
2025
- ...this.getCustomHeaders(),
2026
- "Content-Type": "application/json"
2027
- },
2028
- body: JSON.stringify(requestData)
2044
+ if (exceptionWithStack.stack) currentException.stacktrace = {
2045
+ type: "raw",
2046
+ frames: exceptionWithStack.stack
2029
2047
  };
2030
- this._logger.info("Flags URL", url);
2031
- return this.fetchWithRetry(url, fetchOptions, {
2032
- retryCount: 0
2033
- }, this.featureFlagsRequestTimeoutMs).then((response) => response.json()).then((response) => ({
2034
- success: true,
2035
- response: normalizeFlagsResponse(response)
2036
- })).catch((error) => {
2037
- this._events.emit("error", error);
2038
- return {
2039
- success: false,
2040
- error: this.categorizeRequestError(error)
2041
- };
2042
- });
2048
+ const exceptionList = [
2049
+ currentException
2050
+ ];
2051
+ if (null != exceptionWithStack.cause) exceptionList.push(...this.convertToExceptionList(exceptionWithStack.cause, {
2052
+ ...mechanism,
2053
+ handled: true
2054
+ }));
2055
+ return exceptionList;
2043
2056
  }
2044
- categorizeRequestError(error) {
2045
- if (error instanceof PostHogFetchHttpError) return {
2046
- type: "api_error",
2047
- statusCode: error.status
2048
- };
2049
- if (error instanceof PostHogFetchNetworkError) {
2050
- const cause = error.error;
2051
- if (cause instanceof Error && ("AbortError" === cause.name || "TimeoutError" === cause.name)) return {
2052
- type: "timeout"
2053
- };
2054
- return {
2055
- type: "connection_error"
2056
- };
2057
- }
2058
- return {
2059
- type: "unknown_error"
2057
+ buildParsingContext(hint) {
2058
+ const context = {
2059
+ chunkIdMap: getFilenameToChunkIdMap(this.stackParser),
2060
+ skipFirstLines: hint.skipFirstLines ?? 1
2060
2061
  };
2062
+ return context;
2061
2063
  }
2062
- async getFeatureFlagStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
2063
- await this._initPromise;
2064
- const flagDetailResponse = await this.getFeatureFlagDetailStateless(key, distinctId, groups, personProperties, groupProperties, disableGeoip);
2065
- if (void 0 === flagDetailResponse) return {
2066
- response: void 0,
2067
- requestId: void 0
2064
+ buildCoercingContext(mechanism, hint, depth = 0) {
2065
+ const coerce = (input, depth2) => {
2066
+ if (!(depth2 <= MAX_CAUSE_RECURSION)) return;
2067
+ {
2068
+ const ctx = this.buildCoercingContext(mechanism, hint, depth2);
2069
+ return this.applyCoercers(input, ctx);
2070
+ }
2068
2071
  };
2069
- let response = getFeatureFlagValue(flagDetailResponse.response);
2070
- if (void 0 === response) response = false;
2071
- return {
2072
- response,
2073
- requestId: flagDetailResponse.requestId
2072
+ const context = {
2073
+ ...hint,
2074
+ syntheticException: 0 == depth ? hint.syntheticException : void 0,
2075
+ mechanism,
2076
+ apply: (input) => coerce(input, depth),
2077
+ next: (input) => coerce(input, depth + 1)
2074
2078
  };
2079
+ return context;
2075
2080
  }
2076
- async getFeatureFlagDetailStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
2077
- await this._initPromise;
2078
- const flagsResponse = await this.getFeatureFlagDetailsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, [
2079
- key
2080
- ]);
2081
- if (void 0 === flagsResponse) return;
2082
- const featureFlags = flagsResponse.flags;
2083
- const flagDetail = featureFlags[key];
2081
+ };
2082
+
2083
+ // ../../node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
2084
+ var UNKNOWN_FUNCTION = "?";
2085
+ function createFrame(platform, filename, func, lineno, colno) {
2086
+ const frame = {
2087
+ platform,
2088
+ filename,
2089
+ function: "<anonymous>" === func ? UNKNOWN_FUNCTION : func,
2090
+ in_app: true
2091
+ };
2092
+ if (!isUndefined(lineno)) frame.lineno = lineno;
2093
+ if (!isUndefined(colno)) frame.colno = colno;
2094
+ return frame;
2095
+ }
2096
+
2097
+ // ../../node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
2098
+ var extractSafariExtensionDetails = (func, filename) => {
2099
+ const isSafariExtension = -1 !== func.indexOf("safari-extension");
2100
+ const isSafariWebExtension = -1 !== func.indexOf("safari-web-extension");
2101
+ return isSafariExtension || isSafariWebExtension ? [
2102
+ -1 !== func.indexOf("@") ? func.split("@")[0] : UNKNOWN_FUNCTION,
2103
+ isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`
2104
+ ] : [
2105
+ func,
2106
+ filename
2107
+ ];
2108
+ };
2109
+
2110
+ // ../../node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
2111
+ var chromeRegexNoFnName = /^\s*at (\S+?)(?::(\d+))(?::(\d+))\s*$/i;
2112
+ var chromeRegex = /^\s*at (?:(.+?\)(?: \[.+\])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
2113
+ var chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
2114
+ var chromeStackLineParser = (line, platform) => {
2115
+ const noFnParts = chromeRegexNoFnName.exec(line);
2116
+ if (noFnParts) {
2117
+ const [, filename, line2, col] = noFnParts;
2118
+ return createFrame(platform, filename, UNKNOWN_FUNCTION, +line2, +col);
2119
+ }
2120
+ const parts = chromeRegex.exec(line);
2121
+ if (parts) {
2122
+ const isEval = parts[2] && 0 === parts[2].indexOf("eval");
2123
+ if (isEval) {
2124
+ const subMatch = chromeEvalRegex.exec(parts[2]);
2125
+ if (subMatch) {
2126
+ parts[2] = subMatch[1];
2127
+ parts[3] = subMatch[2];
2128
+ parts[4] = subMatch[3];
2129
+ }
2130
+ }
2131
+ const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);
2132
+ return createFrame(platform, filename, func, parts[3] ? +parts[3] : void 0, parts[4] ? +parts[4] : void 0);
2133
+ }
2134
+ };
2135
+
2136
+ // ../../node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
2137
+ var geckoREgex = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
2138
+ var geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
2139
+ var geckoStackLineParser = (line, platform) => {
2140
+ const parts = geckoREgex.exec(line);
2141
+ if (parts) {
2142
+ const isEval = parts[3] && parts[3].indexOf(" > eval") > -1;
2143
+ if (isEval) {
2144
+ const subMatch = geckoEvalRegex.exec(parts[3]);
2145
+ if (subMatch) {
2146
+ parts[1] = parts[1] || "eval";
2147
+ parts[3] = subMatch[1];
2148
+ parts[4] = subMatch[2];
2149
+ parts[5] = "";
2150
+ }
2151
+ }
2152
+ let filename = parts[3];
2153
+ let func = parts[1] || UNKNOWN_FUNCTION;
2154
+ [func, filename] = extractSafariExtensionDetails(func, filename);
2155
+ return createFrame(platform, filename, func, parts[4] ? +parts[4] : void 0, parts[5] ? +parts[5] : void 0);
2156
+ }
2157
+ };
2158
+
2159
+ // ../../node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
2160
+ var winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:[-a-z]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
2161
+ var winjsStackLineParser = (line, platform) => {
2162
+ const parts = winjsRegex.exec(line);
2163
+ return parts ? createFrame(platform, parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : void 0) : void 0;
2164
+ };
2165
+
2166
+ // ../../node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
2167
+ var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
2168
+ var opera10StackLineParser = (line, platform) => {
2169
+ const parts = opera10Regex.exec(line);
2170
+ return parts ? createFrame(platform, parts[2], parts[3] || UNKNOWN_FUNCTION, +parts[1]) : void 0;
2171
+ };
2172
+ var opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\(.*\))? in (.*):\s*$/i;
2173
+ var opera11StackLineParser = (line, platform) => {
2174
+ const parts = opera11Regex.exec(line);
2175
+ return parts ? createFrame(platform, parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : void 0;
2176
+ };
2177
+
2178
+ // ../../node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
2179
+ var FILENAME_MATCH = /^\s*[-]{4,}$/;
2180
+ var FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
2181
+ var nodeStackLineParser = (line, platform) => {
2182
+ const lineMatch = line.match(FULL_MATCH);
2183
+ if (lineMatch) {
2184
+ let object;
2185
+ let method;
2186
+ let functionName;
2187
+ let typeName;
2188
+ let methodName;
2189
+ if (lineMatch[1]) {
2190
+ functionName = lineMatch[1];
2191
+ let methodStart = functionName.lastIndexOf(".");
2192
+ if ("." === functionName[methodStart - 1]) methodStart--;
2193
+ if (methodStart > 0) {
2194
+ object = functionName.slice(0, methodStart);
2195
+ method = functionName.slice(methodStart + 1);
2196
+ const objectEnd = object.indexOf(".Module");
2197
+ if (objectEnd > 0) {
2198
+ functionName = functionName.slice(objectEnd + 1);
2199
+ object = object.slice(0, objectEnd);
2200
+ }
2201
+ }
2202
+ typeName = void 0;
2203
+ }
2204
+ if (method) {
2205
+ typeName = object;
2206
+ methodName = method;
2207
+ }
2208
+ if ("<anonymous>" === method) {
2209
+ methodName = void 0;
2210
+ functionName = void 0;
2211
+ }
2212
+ if (void 0 === functionName) {
2213
+ methodName = methodName || UNKNOWN_FUNCTION;
2214
+ functionName = typeName ? `${typeName}.${methodName}` : methodName;
2215
+ }
2216
+ let filename = lineMatch[2]?.startsWith("file://") ? lineMatch[2].slice(7) : lineMatch[2];
2217
+ const isNative = "native" === lineMatch[5];
2218
+ if (filename?.match(/\/[A-Z]:/)) filename = filename.slice(1);
2219
+ if (!filename && lineMatch[5] && !isNative) filename = lineMatch[5];
2084
2220
  return {
2085
- response: flagDetail,
2086
- requestId: flagsResponse.requestId,
2087
- evaluatedAt: flagsResponse.evaluatedAt
2221
+ filename: filename ? decodeURI(filename) : void 0,
2222
+ module: void 0,
2223
+ function: functionName,
2224
+ lineno: _parseIntOrUndefined(lineMatch[3]),
2225
+ colno: _parseIntOrUndefined(lineMatch[4]),
2226
+ in_app: filenameIsInApp(filename || "", isNative),
2227
+ platform
2088
2228
  };
2089
2229
  }
2090
- async getFeatureFlagPayloadStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
2091
- await this._initPromise;
2092
- const payloads = await this.getFeatureFlagPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, [
2093
- key
2094
- ]);
2095
- if (!payloads) return;
2096
- const response = payloads[key];
2097
- if (void 0 === response) return null;
2098
- return response;
2230
+ if (line.match(FILENAME_MATCH)) return {
2231
+ filename: line,
2232
+ platform
2233
+ };
2234
+ };
2235
+ function filenameIsInApp(filename, isNative = false) {
2236
+ const isInternal = isNative || filename && !filename.startsWith("/") && !filename.match(/^[A-Z]:/) && !filename.startsWith(".") && !filename.match(/^[a-zA-Z]([a-zA-Z0-9.\-+])*:\/\//);
2237
+ return !isInternal && void 0 !== filename && !filename.includes("node_modules/");
2238
+ }
2239
+ function _parseIntOrUndefined(input) {
2240
+ return parseInt(input || "", 10) || void 0;
2241
+ }
2242
+
2243
+ // ../../node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
2244
+ var WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
2245
+ var STACKTRACE_FRAME_LIMIT = 50;
2246
+ function reverseAndStripFrames(stack) {
2247
+ if (!stack.length) return [];
2248
+ const localStack = Array.from(stack);
2249
+ localStack.reverse();
2250
+ return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map((frame) => ({
2251
+ ...frame,
2252
+ filename: frame.filename || getLastStackFrame(localStack).filename,
2253
+ function: frame.function || UNKNOWN_FUNCTION
2254
+ }));
2255
+ }
2256
+ function getLastStackFrame(arr) {
2257
+ return arr[arr.length - 1] || {};
2258
+ }
2259
+ function createDefaultStackParser() {
2260
+ return createStackParser("web:javascript", chromeStackLineParser, geckoStackLineParser);
2261
+ }
2262
+ function createStackParser(platform, ...parsers) {
2263
+ return (stack, skipFirstLines = 0) => {
2264
+ const frames = [];
2265
+ const lines = stack.split("\n");
2266
+ for (let i2 = skipFirstLines; i2 < lines.length; i2++) {
2267
+ const line = lines[i2];
2268
+ if (line.length > 1024) continue;
2269
+ const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, "$1") : line;
2270
+ if (!cleanedLine.match(/\S*Error: /)) {
2271
+ for (const parser of parsers) {
2272
+ const frame = parser(cleanedLine, platform);
2273
+ if (frame) {
2274
+ frames.push(frame);
2275
+ break;
2276
+ }
2277
+ }
2278
+ if (frames.length >= STACKTRACE_FRAME_LIMIT) break;
2279
+ }
2280
+ }
2281
+ return reverseAndStripFrames(frames);
2282
+ };
2283
+ }
2284
+
2285
+ // ../../node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
2286
+ var DOMExceptionCoercer = class {
2287
+ match(err) {
2288
+ return this.isDOMException(err) || this.isDOMError(err);
2099
2289
  }
2100
- async getFeatureFlagPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
2101
- await this._initPromise;
2102
- const payloads = (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate)).payloads;
2103
- return payloads;
2290
+ coerce(err, ctx) {
2291
+ const hasStack = isString(err.stack);
2292
+ return {
2293
+ type: this.getType(err),
2294
+ value: this.getValue(err),
2295
+ stack: hasStack ? err.stack : void 0,
2296
+ cause: err.cause ? ctx.next(err.cause) : void 0,
2297
+ synthetic: false
2298
+ };
2104
2299
  }
2105
- async getFeatureFlagsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
2106
- await this._initPromise;
2107
- return await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate);
2300
+ getType(candidate) {
2301
+ return this.isDOMError(candidate) ? "DOMError" : "DOMException";
2108
2302
  }
2109
- async getFeatureFlagsAndPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
2110
- await this._initPromise;
2111
- const featureFlagDetails = await this.getFeatureFlagDetailsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate);
2112
- if (!featureFlagDetails) return {
2113
- flags: void 0,
2114
- payloads: void 0,
2115
- requestId: void 0
2303
+ getValue(err) {
2304
+ const name = err.name || (this.isDOMError(err) ? "DOMError" : "DOMException");
2305
+ const message = err.message ? `${name}: ${err.message}` : name;
2306
+ return message;
2307
+ }
2308
+ isDOMException(err) {
2309
+ return isBuiltin(err, "DOMException");
2310
+ }
2311
+ isDOMError(err) {
2312
+ return isBuiltin(err, "DOMError");
2313
+ }
2314
+ };
2315
+
2316
+ // ../../node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
2317
+ var ErrorCoercer = class {
2318
+ match(err) {
2319
+ return isPlainError(err);
2320
+ }
2321
+ coerce(err, ctx) {
2322
+ return {
2323
+ type: this.getType(err),
2324
+ value: this.getMessage(err, ctx),
2325
+ stack: this.getStack(err),
2326
+ cause: err.cause ? ctx.next(err.cause) : void 0,
2327
+ synthetic: false
2328
+ };
2329
+ }
2330
+ getType(err) {
2331
+ return err.name || err.constructor.name;
2332
+ }
2333
+ getMessage(err, _ctx) {
2334
+ const message = err.message;
2335
+ if (message.error && "string" == typeof message.error.message) return String(message.error.message);
2336
+ return String(message);
2337
+ }
2338
+ getStack(err) {
2339
+ return err.stacktrace || err.stack || void 0;
2340
+ }
2341
+ };
2342
+
2343
+ // ../../node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
2344
+ var ErrorEventCoercer = class {
2345
+ constructor() {
2346
+ }
2347
+ match(err) {
2348
+ return isErrorEvent(err) && void 0 != err.error;
2349
+ }
2350
+ coerce(err, ctx) {
2351
+ const exceptionLike = ctx.apply(err.error);
2352
+ if (!exceptionLike) return {
2353
+ type: "ErrorEvent",
2354
+ value: err.message,
2355
+ stack: ctx.syntheticException?.stack,
2356
+ synthetic: true
2116
2357
  };
2358
+ return exceptionLike;
2359
+ }
2360
+ };
2361
+
2362
+ // ../../node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
2363
+ var ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
2364
+ var StringCoercer = class {
2365
+ match(input) {
2366
+ return "string" == typeof input;
2367
+ }
2368
+ coerce(input, ctx) {
2369
+ const [type, value] = this.getInfos(input);
2117
2370
  return {
2118
- flags: featureFlagDetails.featureFlags,
2119
- payloads: featureFlagDetails.featureFlagPayloads,
2120
- requestId: featureFlagDetails.requestId
2371
+ type: type ?? "Error",
2372
+ value: value ?? input,
2373
+ stack: ctx.syntheticException?.stack,
2374
+ synthetic: true
2121
2375
  };
2122
2376
  }
2123
- async getFeatureFlagDetailsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
2124
- await this._initPromise;
2125
- const extraPayload = {};
2126
- if (disableGeoip ?? this.disableGeoip) extraPayload["geoip_disable"] = true;
2127
- if (flagKeysToEvaluate) extraPayload["flag_keys_to_evaluate"] = flagKeysToEvaluate;
2128
- const result = await this.getFlags(distinctId, groups, personProperties, groupProperties, extraPayload);
2129
- if (!result.success) return;
2130
- const flagsResponse = result.response;
2131
- 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");
2132
- if (flagsResponse.quotaLimited?.includes("feature_flags")) {
2133
- 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");
2134
- return {
2135
- flags: {},
2136
- featureFlags: {},
2137
- featureFlagPayloads: {},
2138
- requestId: flagsResponse?.requestId,
2139
- quotaLimited: flagsResponse.quotaLimited
2140
- };
2377
+ getInfos(candidate) {
2378
+ let type = "Error";
2379
+ let value = candidate;
2380
+ const groups = candidate.match(ERROR_TYPES_PATTERN);
2381
+ if (groups) {
2382
+ type = groups[1];
2383
+ value = groups[2];
2141
2384
  }
2142
- return flagsResponse;
2385
+ return [
2386
+ type,
2387
+ value
2388
+ ];
2143
2389
  }
2144
- async getSurveysStateless() {
2145
- await this._initPromise;
2146
- if (this.disabled) return [];
2147
- if (true === this.disableSurveys) {
2148
- this._logger.info("Loading surveys is disabled.");
2149
- return [];
2390
+ };
2391
+
2392
+ // ../../node_modules/@posthog/core/dist/error-tracking/types.mjs
2393
+ var severityLevels = [
2394
+ "fatal",
2395
+ "error",
2396
+ "warning",
2397
+ "log",
2398
+ "info",
2399
+ "debug"
2400
+ ];
2401
+
2402
+ // ../../node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
2403
+ function extractExceptionKeysForMessage(err, maxLength = 40) {
2404
+ const keys = Object.keys(err);
2405
+ keys.sort();
2406
+ if (!keys.length) return "[object has no keys]";
2407
+ for (let i2 = keys.length; i2 > 0; i2--) {
2408
+ const serialized = keys.slice(0, i2).join(", ");
2409
+ if (!(serialized.length > maxLength)) {
2410
+ if (i2 === keys.length) return serialized;
2411
+ return serialized.length <= maxLength ? serialized : `${serialized.slice(0, maxLength)}...`;
2150
2412
  }
2151
- const url = `${this.host}/api/surveys/?token=${this.apiKey}`;
2152
- const fetchOptions = {
2153
- method: "GET",
2154
- headers: {
2155
- ...this.getCustomHeaders(),
2156
- "Content-Type": "application/json"
2157
- }
2158
- };
2159
- const response = await this.fetchWithRetry(url, fetchOptions).then((response2) => {
2160
- if (200 !== response2.status || !response2.json) {
2161
- const msg = `Surveys API could not be loaded: ${response2.status}`;
2162
- const error = new Error(msg);
2163
- this._logger.error(error);
2164
- this._events.emit("error", new Error(msg));
2165
- return;
2166
- }
2167
- return response2.json();
2168
- }).catch((error) => {
2169
- this._logger.error("Surveys API could not be loaded", error);
2170
- this._events.emit("error", error);
2171
- });
2172
- const newSurveys = response?.surveys;
2173
- if (newSurveys) this._logger.info("Surveys fetched from API: ", JSON.stringify(newSurveys));
2174
- return newSurveys ?? [];
2175
2413
  }
2176
- get props() {
2177
- if (!this._props) this._props = this.getPersistedProperty(types_PostHogPersistedProperty.Props);
2178
- return this._props || {};
2414
+ return "";
2415
+ }
2416
+
2417
+ // ../../node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
2418
+ var ObjectCoercer = class {
2419
+ match(candidate) {
2420
+ return "object" == typeof candidate && null !== candidate;
2179
2421
  }
2180
- set props(val) {
2181
- this._props = val;
2422
+ coerce(candidate, ctx) {
2423
+ const errorProperty = this.getErrorPropertyFromObject(candidate);
2424
+ if (errorProperty) return ctx.apply(errorProperty);
2425
+ return {
2426
+ type: this.getType(candidate),
2427
+ value: this.getValue(candidate),
2428
+ stack: ctx.syntheticException?.stack,
2429
+ level: this.isSeverityLevel(candidate.level) ? candidate.level : "error",
2430
+ synthetic: true
2431
+ };
2182
2432
  }
2183
- async register(properties) {
2184
- this.wrap(() => {
2185
- this.props = {
2186
- ...this.props,
2187
- ...properties
2188
- };
2189
- this.setPersistedProperty(types_PostHogPersistedProperty.Props, this.props);
2190
- });
2433
+ getType(err) {
2434
+ return isEvent(err) ? err.constructor.name : "Error";
2191
2435
  }
2192
- async unregister(property) {
2193
- this.wrap(() => {
2194
- delete this.props[property];
2195
- this.setPersistedProperty(types_PostHogPersistedProperty.Props, this.props);
2196
- });
2436
+ getValue(err) {
2437
+ if ("name" in err && "string" == typeof err.name) {
2438
+ let message = `'${err.name}' captured as exception`;
2439
+ if ("message" in err && "string" == typeof err.message) message += ` with message: '${err.message}'`;
2440
+ return message;
2441
+ }
2442
+ if ("message" in err && "string" == typeof err.message) return err.message;
2443
+ const className = this.getObjectClassName(err);
2444
+ const keys = extractExceptionKeysForMessage(err);
2445
+ return `${className && "Object" !== className ? `'${className}'` : "Object"} captured as exception with keys: ${keys}`;
2197
2446
  }
2198
- processBeforeEnqueue(message) {
2199
- return message;
2447
+ isSeverityLevel(x) {
2448
+ return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;
2200
2449
  }
2201
- async flushStorage() {
2450
+ getErrorPropertyFromObject(obj) {
2451
+ for (const prop in obj) if (Object.prototype.hasOwnProperty.call(obj, prop)) {
2452
+ const value = obj[prop];
2453
+ if (isError(value)) return value;
2454
+ }
2202
2455
  }
2203
- enqueue(type, _message, options) {
2204
- this.wrap(() => {
2205
- if (this.optedOut) return void this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.optIn()");
2206
- let message = this.prepareMessage(type, _message, options);
2207
- message = this.processBeforeEnqueue(message);
2208
- if (null === message) return;
2209
- const queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
2210
- if (queue.length >= this.maxQueueSize) {
2211
- queue.shift();
2212
- this._logger.info("Queue is full, the oldest event is dropped.");
2213
- }
2214
- queue.push({
2215
- message
2216
- });
2217
- this.setPersistedProperty(types_PostHogPersistedProperty.Queue, queue);
2218
- this._events.emit(type, message);
2219
- if (queue.length >= this.flushAt) this.flushBackground();
2220
- if (this.flushInterval && !this._flushTimer) this._flushTimer = safeSetTimeout(() => this.flushBackground(), this.flushInterval);
2221
- });
2456
+ getObjectClassName(obj) {
2457
+ try {
2458
+ const prototype = Object.getPrototypeOf(obj);
2459
+ return prototype ? prototype.constructor.name : void 0;
2460
+ } catch (e) {
2461
+ return;
2462
+ }
2222
2463
  }
2223
- async sendImmediate(type, _message, options) {
2224
- if (this.disabled) return void this._logger.warn("The client is disabled");
2225
- if (!this._isInitialized) await this._initPromise;
2226
- if (this.optedOut) return void this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.optIn()");
2227
- let message = this.prepareMessage(type, _message, options);
2228
- message = this.processBeforeEnqueue(message);
2229
- if (null === message) return;
2230
- const data = {
2231
- api_key: this.apiKey,
2232
- batch: [
2233
- message
2234
- ],
2235
- sent_at: currentISOTime()
2464
+ };
2465
+
2466
+ // ../../node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
2467
+ var EventCoercer = class {
2468
+ match(err) {
2469
+ return isEvent(err);
2470
+ }
2471
+ coerce(evt, ctx) {
2472
+ const constructorName = evt.constructor.name;
2473
+ return {
2474
+ type: constructorName,
2475
+ value: `${constructorName} captured as exception with keys: ${extractExceptionKeysForMessage(evt)}`,
2476
+ stack: ctx.syntheticException?.stack,
2477
+ synthetic: true
2236
2478
  };
2237
- if (this.historicalMigration) data.historical_migration = true;
2238
- const payload = JSON.stringify(data);
2239
- const url = `${this.host}/batch/`;
2240
- const gzippedPayload = this.disableCompression ? null : await gzipCompress(payload, this.isDebug);
2241
- const fetchOptions = {
2242
- method: "POST",
2243
- headers: {
2244
- ...this.getCustomHeaders(),
2245
- "Content-Type": "application/json",
2246
- ...null !== gzippedPayload && {
2247
- "Content-Encoding": "gzip"
2248
- }
2249
- },
2250
- body: gzippedPayload || payload
2479
+ }
2480
+ };
2481
+
2482
+ // ../../node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
2483
+ var PrimitiveCoercer = class {
2484
+ match(candidate) {
2485
+ return isPrimitive(candidate);
2486
+ }
2487
+ coerce(value, ctx) {
2488
+ return {
2489
+ type: "Error",
2490
+ value: `Primitive value captured as exception: ${String(value)}`,
2491
+ stack: ctx.syntheticException?.stack,
2492
+ synthetic: true
2251
2493
  };
2494
+ }
2495
+ };
2496
+
2497
+ // ../../node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
2498
+ var PromiseRejectionEventCoercer = class {
2499
+ match(err) {
2500
+ return isBuiltin(err, "PromiseRejectionEvent") || this.isCustomEventWrappingRejection(err);
2501
+ }
2502
+ isCustomEventWrappingRejection(err) {
2503
+ if (!isEvent(err)) return false;
2252
2504
  try {
2253
- const response = await this.fetchWithRetry(url, fetchOptions);
2254
- await response.body?.cancel()?.catch(() => {
2255
- });
2256
- } catch (err) {
2257
- this._events.emit("error", err);
2505
+ const detail = err.detail;
2506
+ return null != detail && "object" == typeof detail && "reason" in detail;
2507
+ } catch {
2508
+ return false;
2258
2509
  }
2259
2510
  }
2260
- prepareMessage(type, _message, options) {
2261
- const message = {
2262
- ..._message,
2263
- type,
2264
- library: this.getLibraryId(),
2265
- library_version: this.getLibraryVersion(),
2266
- timestamp: options?.timestamp ? options?.timestamp : currentISOTime(),
2267
- uuid: options?.uuid ? options.uuid : uuidv7()
2511
+ coerce(err, ctx) {
2512
+ const reason = this.getUnhandledRejectionReason(err);
2513
+ if (isPrimitive(reason)) return {
2514
+ type: "UnhandledRejection",
2515
+ value: `Non-Error promise rejection captured with value: ${String(reason)}`,
2516
+ stack: ctx.syntheticException?.stack,
2517
+ synthetic: true
2268
2518
  };
2269
- const addGeoipDisableProperty = options?.disableGeoip ?? this.disableGeoip;
2270
- if (addGeoipDisableProperty) {
2271
- if (!message.properties) message.properties = {};
2272
- message["properties"]["$geoip_disable"] = true;
2273
- }
2274
- if (message.distinctId) {
2275
- message.distinct_id = message.distinctId;
2276
- delete message.distinctId;
2277
- }
2278
- return message;
2519
+ return ctx.apply(reason);
2279
2520
  }
2280
- clearFlushTimer() {
2281
- if (this._flushTimer) {
2282
- clearTimeout(this._flushTimer);
2283
- this._flushTimer = void 0;
2521
+ getUnhandledRejectionReason(error) {
2522
+ try {
2523
+ if ("reason" in error) return error.reason;
2524
+ if ("detail" in error && null != error.detail && "object" == typeof error.detail && "reason" in error.detail) return error.detail.reason;
2525
+ } catch {
2284
2526
  }
2527
+ return error;
2285
2528
  }
2286
- flushBackground() {
2287
- this.flush().catch(async (err) => {
2288
- await logFlushError(err);
2289
- });
2290
- }
2291
- async flush() {
2292
- if (this.disabled) return;
2293
- const nextFlushPromise = allSettled([
2294
- this.flushPromise
2295
- ]).then(() => this._flush());
2296
- this.flushPromise = nextFlushPromise;
2297
- this.addPendingPromise(nextFlushPromise);
2298
- allSettled([
2299
- nextFlushPromise
2300
- ]).then(() => {
2301
- if (this.flushPromise === nextFlushPromise) this.flushPromise = null;
2302
- });
2303
- return nextFlushPromise;
2529
+ };
2530
+
2531
+ // ../../node_modules/@posthog/core/dist/error-tracking/utils.mjs
2532
+ var ReduceableCache = class {
2533
+ constructor(_maxSize) {
2534
+ this._maxSize = _maxSize;
2535
+ this._cache = /* @__PURE__ */ new Map();
2304
2536
  }
2305
- getCustomHeaders() {
2306
- const customUserAgent = this.getCustomUserAgent();
2307
- const headers = {};
2308
- if (customUserAgent && "" !== customUserAgent) headers["User-Agent"] = customUserAgent;
2309
- return headers;
2537
+ get(key) {
2538
+ const value = this._cache.get(key);
2539
+ if (void 0 === value) return;
2540
+ this._cache.delete(key);
2541
+ this._cache.set(key, value);
2542
+ return value;
2310
2543
  }
2311
- async _flush() {
2312
- this.clearFlushTimer();
2313
- await this._initPromise;
2314
- let queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
2315
- if (!queue.length) return;
2316
- const sentMessages = [];
2317
- const originalQueueLength = queue.length;
2318
- while (queue.length > 0 && sentMessages.length < originalQueueLength) {
2319
- const batchItems = queue.slice(0, this.maxBatchSize);
2320
- const batchMessages = batchItems.map((item) => item.message);
2321
- const persistQueueChange = async () => {
2322
- const refreshedQueue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
2323
- const newQueue = refreshedQueue.slice(batchItems.length);
2324
- this.setPersistedProperty(types_PostHogPersistedProperty.Queue, newQueue);
2325
- queue = newQueue;
2326
- await this.flushStorage();
2327
- };
2328
- const data = {
2329
- api_key: this.apiKey,
2330
- batch: batchMessages,
2331
- sent_at: currentISOTime()
2332
- };
2333
- if (this.historicalMigration) data.historical_migration = true;
2334
- const payload = JSON.stringify(data);
2335
- const url = `${this.host}/batch/`;
2336
- const gzippedPayload = this.disableCompression ? null : await gzipCompress(payload, this.isDebug);
2337
- const fetchOptions = {
2338
- method: "POST",
2339
- headers: {
2340
- ...this.getCustomHeaders(),
2341
- "Content-Type": "application/json",
2342
- ...null !== gzippedPayload && {
2343
- "Content-Encoding": "gzip"
2344
- }
2345
- },
2346
- body: gzippedPayload || payload
2347
- };
2348
- const retryOptions = {
2349
- retryCheck: (err) => {
2350
- if (isPostHogFetchContentTooLargeError(err)) return false;
2351
- return isPostHogFetchError(err);
2352
- }
2353
- };
2354
- try {
2355
- const response = await this.fetchWithRetry(url, fetchOptions, retryOptions);
2356
- await response.body?.cancel()?.catch(() => {
2357
- });
2358
- } catch (err) {
2359
- if (isPostHogFetchContentTooLargeError(err) && batchMessages.length > 1) {
2360
- this.maxBatchSize = Math.max(1, Math.floor(batchMessages.length / 2));
2361
- this._logger.warn(`Received 413 when sending batch of size ${batchMessages.length}, reducing batch size to ${this.maxBatchSize}`);
2362
- continue;
2363
- }
2364
- if (!(err instanceof PostHogFetchNetworkError)) await persistQueueChange();
2365
- this._events.emit("error", err);
2366
- throw err;
2367
- }
2368
- await persistQueueChange();
2369
- sentMessages.push(...batchMessages);
2370
- }
2371
- this._events.emit("flush", sentMessages);
2544
+ set(key, value) {
2545
+ this._cache.set(key, value);
2372
2546
  }
2373
- async _sendLogsBatch(payload) {
2374
- if (this.disabled) return {
2375
- kind: "fatal",
2376
- error: new Error("The client is disabled")
2377
- };
2378
- const serialized = JSON.stringify(payload);
2379
- const url = `${this.host}/i/v1/logs?token=${encodeURIComponent(this.apiKey)}`;
2380
- const gzippedPayload = this.disableCompression ? null : await gzipCompress(serialized, this.isDebug);
2381
- const fetchOptions = {
2382
- method: "POST",
2383
- headers: {
2384
- ...this.getCustomHeaders(),
2385
- "Content-Type": "application/json",
2386
- ...null !== gzippedPayload && {
2387
- "Content-Encoding": "gzip"
2388
- }
2389
- },
2390
- body: gzippedPayload || serialized
2391
- };
2392
- try {
2393
- await this.fetchWithRetry(url, fetchOptions, {
2394
- retryCheck: (err) => {
2395
- if (isPostHogFetchContentTooLargeError(err)) return false;
2396
- return isPostHogFetchError(err);
2397
- }
2398
- });
2399
- return {
2400
- kind: "ok"
2401
- };
2402
- } catch (err) {
2403
- if (isPostHogFetchContentTooLargeError(err)) return {
2404
- kind: "too-large"
2405
- };
2406
- if (err instanceof PostHogFetchNetworkError) return {
2407
- kind: "retry-later",
2408
- error: err
2409
- };
2410
- return {
2411
- kind: "fatal",
2412
- error: err
2413
- };
2547
+ reduce() {
2548
+ while (this._cache.size >= this._maxSize) {
2549
+ const value = this._cache.keys().next().value;
2550
+ if (value) this._cache.delete(value);
2414
2551
  }
2415
2552
  }
2416
- async fetchWithRetry(url, options, retryOptions, requestTimeout) {
2417
- const body = options.body ? options.body : "";
2418
- let reqByteLength = -1;
2419
- try {
2420
- reqByteLength = body instanceof Blob ? body.size : Buffer.byteLength(body, STRING_FORMAT);
2421
- } catch {
2422
- if (body instanceof Blob) reqByteLength = body.size;
2423
- else {
2424
- const encoded = new TextEncoder().encode(body);
2425
- reqByteLength = encoded.length;
2426
- }
2553
+ };
2554
+
2555
+ // ../../node_modules/@posthog/core/dist/error-tracking/exception-steps.mjs
2556
+ var EXCEPTION_STEP_INTERNAL_FIELDS = {
2557
+ MESSAGE: "$message",
2558
+ TIMESTAMP: "$timestamp"
2559
+ };
2560
+ var RESERVED_EXCEPTION_STEP_KEYS = /* @__PURE__ */ new Set([
2561
+ EXCEPTION_STEP_INTERNAL_FIELDS.MESSAGE,
2562
+ EXCEPTION_STEP_INTERNAL_FIELDS.TIMESTAMP
2563
+ ]);
2564
+ var DEFAULT_EXCEPTION_STEPS_CONFIG = {
2565
+ enabled: true,
2566
+ max_bytes: 32768
2567
+ };
2568
+ function resolveExceptionStepsConfig(config) {
2569
+ if (!config) return {
2570
+ ...DEFAULT_EXCEPTION_STEPS_CONFIG
2571
+ };
2572
+ return {
2573
+ enabled: config.enabled ?? DEFAULT_EXCEPTION_STEPS_CONFIG.enabled,
2574
+ max_bytes: normalizePositiveInteger(config.max_bytes, DEFAULT_EXCEPTION_STEPS_CONFIG.max_bytes)
2575
+ };
2576
+ }
2577
+ function stripReservedExceptionStepFields(properties) {
2578
+ if (!properties) return {
2579
+ sanitizedProperties: {},
2580
+ droppedKeys: []
2581
+ };
2582
+ const droppedKeys = [];
2583
+ const sanitizedProperties = Object.keys(properties).reduce((acc, key) => {
2584
+ if (RESERVED_EXCEPTION_STEP_KEYS.has(key)) {
2585
+ droppedKeys.push(key);
2586
+ return acc;
2427
2587
  }
2428
- return await retriable(async () => {
2429
- const ctrl = new AbortController();
2430
- const timeoutMs = requestTimeout ?? this.requestTimeout;
2431
- const timer = safeSetTimeout(() => ctrl.abort(), timeoutMs);
2432
- let res = null;
2433
- try {
2434
- res = await this.fetch(url, {
2435
- signal: ctrl.signal,
2436
- ...options
2437
- });
2438
- } catch (e) {
2439
- throw new PostHogFetchNetworkError(e);
2440
- } finally {
2441
- clearTimeout(timer);
2442
- }
2443
- const isNoCors = "no-cors" === options.mode;
2444
- if (!isNoCors && (res.status < 200 || res.status >= 400)) throw new PostHogFetchHttpError(res, reqByteLength);
2445
- return res;
2446
- }, {
2447
- ...this._retryOptions,
2448
- ...retryOptions
2588
+ acc[key] = properties[key];
2589
+ return acc;
2590
+ }, {});
2591
+ return {
2592
+ sanitizedProperties,
2593
+ droppedKeys
2594
+ };
2595
+ }
2596
+ var ExceptionStepsBuffer = class {
2597
+ constructor(config) {
2598
+ this._entries = [];
2599
+ this._totalBytes = 0;
2600
+ this._config = resolveExceptionStepsConfig(config);
2601
+ }
2602
+ setConfig(config) {
2603
+ this._config = resolveExceptionStepsConfig(config);
2604
+ this._trimToMaxBytes();
2605
+ }
2606
+ add(step) {
2607
+ const serialized = normalizeAndSerializeStep(step);
2608
+ if (!serialized) return;
2609
+ const bytes = getUtf8ByteLength(serialized.json);
2610
+ if (bytes > this._config.max_bytes) return;
2611
+ this._entries.push({
2612
+ step: serialized.step,
2613
+ bytes
2449
2614
  });
2615
+ this._totalBytes += bytes;
2616
+ this._trimToMaxBytes();
2450
2617
  }
2451
- async _shutdown(shutdownTimeoutMs = 3e4) {
2452
- await this._initPromise;
2453
- let hasTimedOut = false;
2454
- this.clearFlushTimer();
2455
- if (this.disabled) return;
2456
- const doShutdown = async () => {
2457
- try {
2458
- await this.promiseQueue.join();
2459
- while (true) {
2460
- const queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
2461
- if (0 === queue.length) break;
2462
- await this.flush();
2463
- if (hasTimedOut) break;
2464
- }
2465
- } catch (e) {
2466
- if (!isPostHogFetchError(e)) throw e;
2467
- await logFlushError(e);
2468
- }
2469
- };
2470
- let timeoutHandle;
2471
- try {
2472
- return await Promise.race([
2473
- new Promise((_, reject) => {
2474
- timeoutHandle = safeSetTimeout(() => {
2475
- this._logger.error("Timed out while shutting down PostHog");
2476
- hasTimedOut = true;
2477
- reject("Timeout while shutting down PostHog. Some events may not have been sent.");
2478
- }, shutdownTimeoutMs);
2479
- }),
2480
- doShutdown()
2481
- ]);
2482
- } finally {
2483
- clearTimeout(timeoutHandle);
2618
+ getAttachable() {
2619
+ return this._entries.map((e) => e.step);
2620
+ }
2621
+ clear() {
2622
+ this._entries = [];
2623
+ this._totalBytes = 0;
2624
+ }
2625
+ size() {
2626
+ return this._entries.length;
2627
+ }
2628
+ _trimToMaxBytes() {
2629
+ while (this._totalBytes > this._config.max_bytes && this._entries.length > 0) {
2630
+ const evicted = this._entries.shift();
2631
+ if (evicted) this._totalBytes -= evicted.bytes;
2484
2632
  }
2485
2633
  }
2486
- async shutdown(shutdownTimeoutMs = 3e4) {
2487
- 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");
2488
- else this.shutdownPromise = this._shutdown(shutdownTimeoutMs).finally(() => {
2489
- this.shutdownPromise = null;
2634
+ };
2635
+ function normalizePositiveInteger(input, fallback) {
2636
+ if (!isNumber(input) || input === 1 / 0 || input === -1 / 0) return fallback;
2637
+ const normalized = Math.floor(input);
2638
+ if (normalized < 0) return fallback;
2639
+ return normalized;
2640
+ }
2641
+ function normalizeAndSerializeStep(step) {
2642
+ const json = safeStringify(step);
2643
+ if (!json) return;
2644
+ try {
2645
+ const parsed = JSON.parse(json);
2646
+ if (!isObject(parsed)) return;
2647
+ const parsedStep = parsed;
2648
+ const message = parsedStep[EXCEPTION_STEP_INTERNAL_FIELDS.MESSAGE];
2649
+ const timestamp = parsedStep[EXCEPTION_STEP_INTERNAL_FIELDS.TIMESTAMP];
2650
+ if (!isString(message) || 0 === message.trim().length) return;
2651
+ if (!isString(timestamp) && !isNumber(timestamp)) return;
2652
+ return {
2653
+ step: parsedStep,
2654
+ json
2655
+ };
2656
+ } catch {
2657
+ return;
2658
+ }
2659
+ }
2660
+ function safeStringify(value) {
2661
+ const seen = /* @__PURE__ */ new WeakSet();
2662
+ try {
2663
+ return JSON.stringify(value, (_key, replacementValue) => {
2664
+ if ("bigint" == typeof replacementValue) return replacementValue.toString();
2665
+ if ("function" == typeof replacementValue || "symbol" == typeof replacementValue) return;
2666
+ if (replacementValue instanceof Date) return replacementValue.toISOString();
2667
+ if (replacementValue instanceof Error) return {
2668
+ name: replacementValue.name,
2669
+ message: replacementValue.message,
2670
+ stack: replacementValue.stack
2671
+ };
2672
+ if (replacementValue && "object" == typeof replacementValue) {
2673
+ if (seen.has(replacementValue)) return "[Circular]";
2674
+ seen.add(replacementValue);
2675
+ }
2676
+ return replacementValue;
2490
2677
  });
2491
- return this.shutdownPromise;
2678
+ } catch {
2679
+ return;
2492
2680
  }
2493
- };
2494
-
2495
- // ../../node_modules/@posthog/core/dist/error-tracking/index.mjs
2496
- var error_tracking_exports = {};
2497
- __export(error_tracking_exports, {
2498
- DEFAULT_EXCEPTION_STEPS_CONFIG: () => DEFAULT_EXCEPTION_STEPS_CONFIG,
2499
- DOMExceptionCoercer: () => DOMExceptionCoercer,
2500
- EXCEPTION_STEP_INTERNAL_FIELDS: () => EXCEPTION_STEP_INTERNAL_FIELDS,
2501
- ErrorCoercer: () => ErrorCoercer,
2502
- ErrorEventCoercer: () => ErrorEventCoercer,
2503
- ErrorPropertiesBuilder: () => ErrorPropertiesBuilder,
2504
- EventCoercer: () => EventCoercer,
2505
- ExceptionStepsBuffer: () => ExceptionStepsBuffer,
2506
- ObjectCoercer: () => ObjectCoercer,
2507
- PrimitiveCoercer: () => PrimitiveCoercer,
2508
- PromiseRejectionEventCoercer: () => PromiseRejectionEventCoercer,
2509
- ReduceableCache: () => ReduceableCache,
2510
- StringCoercer: () => StringCoercer,
2511
- chromeStackLineParser: () => chromeStackLineParser,
2512
- createDefaultStackParser: () => createDefaultStackParser,
2513
- createStackParser: () => createStackParser,
2514
- geckoStackLineParser: () => geckoStackLineParser,
2515
- getUtf8ByteLength: () => getUtf8ByteLength,
2516
- nodeStackLineParser: () => nodeStackLineParser,
2517
- opera10StackLineParser: () => opera10StackLineParser,
2518
- opera11StackLineParser: () => opera11StackLineParser,
2519
- resolveExceptionStepsConfig: () => resolveExceptionStepsConfig,
2520
- reverseAndStripFrames: () => reverseAndStripFrames,
2521
- stripReservedExceptionStepFields: () => stripReservedExceptionStepFields,
2522
- winjsStackLineParser: () => winjsStackLineParser
2523
- });
2681
+ }
2682
+ function getUtf8ByteLength(value) {
2683
+ if ("undefined" != typeof TextEncoder) return new TextEncoder().encode(value).length;
2684
+ const encoded = encodeURIComponent(value);
2685
+ let byteLength = 0;
2686
+ for (let i2 = 0; i2 < encoded.length; i2++) if ("%" === encoded[i2]) {
2687
+ byteLength += 1;
2688
+ i2 += 2;
2689
+ } else byteLength += 1;
2690
+ return byteLength;
2691
+ }
2524
2692
 
2525
- // ../../node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
2526
- var parsedStackResults;
2527
- var lastKeysCount;
2528
- var cachedFilenameChunkIds;
2529
- function getFilenameToChunkIdMap(stackParser) {
2530
- const chunkIdMap = globalThis._posthogChunkIds;
2531
- if (!chunkIdMap) return;
2532
- const chunkIdKeys = Object.keys(chunkIdMap);
2533
- if (cachedFilenameChunkIds && chunkIdKeys.length === lastKeysCount) return cachedFilenameChunkIds;
2534
- lastKeysCount = chunkIdKeys.length;
2535
- cachedFilenameChunkIds = chunkIdKeys.reduce((acc, stackKey) => {
2536
- if (!parsedStackResults) parsedStackResults = {};
2537
- const result = parsedStackResults[stackKey];
2538
- if (result) acc[result[0]] = result[1];
2539
- else {
2540
- const parsedStack = stackParser(stackKey);
2541
- for (let i2 = parsedStack.length - 1; i2 >= 0; i2--) {
2542
- const stackFrame = parsedStack[i2];
2543
- const filename = stackFrame?.filename;
2544
- const chunkId = chunkIdMap[stackKey];
2545
- if (filename && chunkId) {
2546
- acc[filename] = chunkId;
2547
- parsedStackResults[stackKey] = [
2548
- filename,
2549
- chunkId
2550
- ];
2551
- break;
2552
- }
2553
- }
2693
+ // ../../node_modules/@posthog/core/dist/posthog-core-stateless.mjs
2694
+ var PostHogFetchHttpError = class extends Error {
2695
+ constructor(response, reqByteLength) {
2696
+ super("HTTP error while fetching PostHog: status=" + response.status + ", reqByteLength=" + reqByteLength), this.response = response, this.reqByteLength = reqByteLength, this.name = "PostHogFetchHttpError";
2697
+ }
2698
+ get status() {
2699
+ return this.response.status;
2700
+ }
2701
+ get text() {
2702
+ return this.response.text();
2703
+ }
2704
+ get json() {
2705
+ return this.response.json();
2706
+ }
2707
+ };
2708
+ var PostHogFetchNetworkError = class extends Error {
2709
+ constructor(error) {
2710
+ super("Network error while fetching PostHog", error instanceof Error ? {
2711
+ cause: error
2712
+ } : {}), this.error = error, this.name = "PostHogFetchNetworkError";
2713
+ }
2714
+ };
2715
+ async function logFlushError(err) {
2716
+ if (err instanceof PostHogFetchHttpError) {
2717
+ let text2 = "";
2718
+ try {
2719
+ text2 = await err.text;
2720
+ } catch {
2554
2721
  }
2555
- return acc;
2556
- }, {});
2557
- return cachedFilenameChunkIds;
2722
+ console.error(`Error while flushing PostHog: message=${err.message}, response body=${text2}`, err);
2723
+ } else console.error("Error while flushing PostHog", err);
2724
+ return Promise.resolve();
2558
2725
  }
2559
-
2560
- // ../../node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
2561
- var MAX_CAUSE_RECURSION = 4;
2562
- var ErrorPropertiesBuilder = class {
2563
- constructor(coercers, stackParser, modifiers = []) {
2564
- this.coercers = coercers;
2565
- this.stackParser = stackParser;
2566
- this.modifiers = modifiers;
2726
+ function isPostHogFetchError(err) {
2727
+ return "object" == typeof err && (err instanceof PostHogFetchHttpError || isPostHogFetchNetworkError(err));
2728
+ }
2729
+ function isPostHogFetchNetworkError(err) {
2730
+ return err instanceof PostHogFetchNetworkError;
2731
+ }
2732
+ function isPostHogFetchContentTooLargeError(err) {
2733
+ return "object" == typeof err && err instanceof PostHogFetchHttpError && 413 === err.status;
2734
+ }
2735
+ function isPostHogEventProperties(value) {
2736
+ return null !== value && "object" == typeof value && !Array.isArray(value);
2737
+ }
2738
+ var PostHogCoreStateless = class {
2739
+ getErrorPropertiesBuilder() {
2740
+ if (!this._errorPropertiesBuilder) this._errorPropertiesBuilder = this.createErrorPropertiesBuilder();
2741
+ return this._errorPropertiesBuilder;
2742
+ }
2743
+ createErrorPropertiesBuilder() {
2744
+ return new ErrorPropertiesBuilder([
2745
+ new ErrorCoercer(),
2746
+ new ObjectCoercer(),
2747
+ new StringCoercer(),
2748
+ new PrimitiveCoercer()
2749
+ ], createDefaultStackParser());
2567
2750
  }
2568
- buildFromUnknown(input, hint = {}) {
2569
- const providedMechanism = hint && hint.mechanism;
2570
- const mechanism = providedMechanism || {
2571
- handled: true,
2572
- type: "generic"
2573
- };
2574
- const coercingContext = this.buildCoercingContext(mechanism, hint, 0);
2575
- const exceptionWithCause = coercingContext.apply(input);
2576
- const parsingContext = this.buildParsingContext(hint);
2577
- const exceptionWithStack = this.parseStacktrace(exceptionWithCause, parsingContext);
2578
- const exceptionList = this.convertToExceptionList(exceptionWithStack, mechanism);
2579
- return {
2580
- $exception_list: exceptionList,
2581
- $exception_level: "error"
2751
+ constructor(apiKey, options = {}) {
2752
+ this.flushPromise = null;
2753
+ this.shutdownPromise = null;
2754
+ this.promiseQueue = new PromiseQueue();
2755
+ this._events = new SimpleEventEmitter();
2756
+ this._isInitialized = false;
2757
+ const normalizedApiKey = "string" == typeof apiKey ? apiKey.trim() : "";
2758
+ const normalizedHost = "string" == typeof options.host ? options.host.trim() : "";
2759
+ const missingApiKey = !normalizedApiKey;
2760
+ this._logger = createLogger("[PostHog]", this.logMsgIfDebug.bind(this));
2761
+ if (missingApiKey) this._logger.error("You must pass your PostHog project's api key. The client will be disabled.");
2762
+ this.apiKey = normalizedApiKey;
2763
+ this.host = removeTrailingSlash(normalizedHost || "https://us.i.posthog.com");
2764
+ this.flushAt = options.flushAt ? Math.max(options.flushAt, 1) : 20;
2765
+ this.maxBatchSize = Math.max(this.flushAt, options.maxBatchSize ?? 100);
2766
+ this.maxQueueSize = Math.max(this.flushAt, options.maxQueueSize ?? 1e3);
2767
+ this.flushInterval = options.flushInterval ?? 1e4;
2768
+ this.preloadFeatureFlags = options.preloadFeatureFlags ?? true;
2769
+ this.defaultOptIn = options.defaultOptIn ?? true;
2770
+ this.disableSurveys = options.disableSurveys ?? false;
2771
+ this._retryOptions = {
2772
+ retryCount: options.fetchRetryCount ?? 3,
2773
+ retryDelay: options.fetchRetryDelay ?? 3e3,
2774
+ retryCheck: isPostHogFetchError
2582
2775
  };
2776
+ this.requestTimeout = options.requestTimeout ?? 1e4;
2777
+ this.featureFlagsRequestTimeoutMs = options.featureFlagsRequestTimeoutMs ?? 3e3;
2778
+ this.remoteConfigRequestTimeoutMs = options.remoteConfigRequestTimeoutMs ?? 3e3;
2779
+ this.disableGeoip = options.disableGeoip ?? true;
2780
+ this.disabled = (options.disabled ?? false) || missingApiKey;
2781
+ this.historicalMigration = options?.historicalMigration ?? false;
2782
+ this._initPromise = Promise.resolve();
2783
+ this._isInitialized = true;
2784
+ this.evaluationContexts = options?.evaluationContexts ?? options?.evaluationEnvironments;
2785
+ if (options?.evaluationEnvironments && !options?.evaluationContexts) this._logger.warn("evaluationEnvironments is deprecated. Use evaluationContexts instead. This property will be removed in a future version.");
2786
+ this.disableCompression = !isGzipSupported() || (options?.disableCompression ?? false);
2583
2787
  }
2584
- async modifyFrames(exceptionList) {
2585
- for (const exc of exceptionList) if (exc.stacktrace && exc.stacktrace.frames && isArray(exc.stacktrace.frames)) exc.stacktrace.frames = await this.applyModifiers(exc.stacktrace.frames);
2586
- return exceptionList;
2788
+ logMsgIfDebug(fn) {
2789
+ if (this.isDebug) fn();
2587
2790
  }
2588
- coerceFallback(ctx) {
2589
- return {
2590
- type: "Error",
2591
- value: "Unknown error",
2592
- stack: ctx.syntheticException?.stack,
2593
- synthetic: true
2594
- };
2791
+ wrap(fn) {
2792
+ if (this.disabled) return void this._logger.warn("The client is disabled");
2793
+ if (this._isInitialized) return fn();
2794
+ this._initPromise.then(() => fn());
2595
2795
  }
2596
- parseStacktrace(err, ctx) {
2597
- let cause;
2598
- if (null != err.cause) cause = this.parseStacktrace(err.cause, ctx);
2599
- let stack;
2600
- if ("" != err.stack && null != err.stack) stack = this.applyChunkIds(this.stackParser(err.stack, err.synthetic ? ctx.skipFirstLines : 0), ctx.chunkIdMap);
2796
+ getCommonEventProperties() {
2601
2797
  return {
2602
- ...err,
2603
- cause,
2604
- stack
2798
+ $lib: this.getLibraryId(),
2799
+ $lib_version: this.getLibraryVersion()
2605
2800
  };
2606
2801
  }
2607
- applyChunkIds(frames, chunkIdMap) {
2608
- return frames.map((frame) => {
2609
- if (frame.filename && chunkIdMap) frame.chunk_id = chunkIdMap[frame.filename];
2610
- return frame;
2802
+ get optedOut() {
2803
+ return this.getPersistedProperty(types_PostHogPersistedProperty.OptedOut) ?? !this.defaultOptIn;
2804
+ }
2805
+ async optIn() {
2806
+ this.wrap(() => {
2807
+ this.setPersistedProperty(types_PostHogPersistedProperty.OptedOut, false);
2611
2808
  });
2612
2809
  }
2613
- applyCoercers(input, ctx) {
2614
- for (const adapter of this.coercers) if (adapter.match(input)) return adapter.coerce(input, ctx);
2615
- return this.coerceFallback(ctx);
2810
+ async optOut() {
2811
+ this.wrap(() => {
2812
+ this.setPersistedProperty(types_PostHogPersistedProperty.OptedOut, true);
2813
+ });
2616
2814
  }
2617
- async applyModifiers(frames) {
2618
- let newFrames = frames;
2619
- for (const modifier of this.modifiers) newFrames = await modifier(newFrames);
2620
- return newFrames;
2815
+ on(event, cb) {
2816
+ return this._events.on(event, cb);
2621
2817
  }
2622
- convertToExceptionList(exceptionWithStack, mechanism) {
2623
- const currentException = {
2624
- type: exceptionWithStack.type,
2625
- value: exceptionWithStack.value,
2626
- mechanism: {
2627
- type: mechanism.type ?? "generic",
2628
- handled: mechanism.handled ?? true,
2629
- synthetic: exceptionWithStack.synthetic ?? false
2630
- }
2631
- };
2632
- if (exceptionWithStack.stack) currentException.stacktrace = {
2633
- type: "raw",
2634
- frames: exceptionWithStack.stack
2635
- };
2636
- const exceptionList = [
2637
- currentException
2638
- ];
2639
- if (null != exceptionWithStack.cause) exceptionList.push(...this.convertToExceptionList(exceptionWithStack.cause, {
2640
- ...mechanism,
2641
- handled: true
2642
- }));
2643
- return exceptionList;
2818
+ debug(enabled = true) {
2819
+ this.removeDebugCallback?.();
2820
+ if (enabled) {
2821
+ const removeDebugCallback = this.on("*", (event, payload) => this._logger.info(event, payload));
2822
+ this.removeDebugCallback = () => {
2823
+ removeDebugCallback();
2824
+ this.removeDebugCallback = void 0;
2825
+ };
2826
+ }
2644
2827
  }
2645
- buildParsingContext(hint) {
2646
- const context = {
2647
- chunkIdMap: getFilenameToChunkIdMap(this.stackParser),
2648
- skipFirstLines: hint.skipFirstLines ?? 1
2649
- };
2650
- return context;
2828
+ get isDebug() {
2829
+ return !!this.removeDebugCallback;
2651
2830
  }
2652
- buildCoercingContext(mechanism, hint, depth = 0) {
2653
- const coerce = (input, depth2) => {
2654
- if (!(depth2 <= MAX_CAUSE_RECURSION)) return;
2655
- {
2656
- const ctx = this.buildCoercingContext(mechanism, hint, depth2);
2657
- return this.applyCoercers(input, ctx);
2831
+ get isDisabled() {
2832
+ return this.disabled;
2833
+ }
2834
+ buildPayload(payload) {
2835
+ return {
2836
+ distinct_id: payload.distinct_id,
2837
+ event: payload.event,
2838
+ properties: {
2839
+ ...payload.properties || {},
2840
+ ...this.getCommonEventProperties()
2658
2841
  }
2659
2842
  };
2660
- const context = {
2661
- ...hint,
2662
- syntheticException: 0 == depth ? hint.syntheticException : void 0,
2663
- mechanism,
2664
- apply: (input) => coerce(input, depth),
2665
- next: (input) => coerce(input, depth + 1)
2843
+ }
2844
+ addPendingPromise(promise) {
2845
+ return this.promiseQueue.add(promise);
2846
+ }
2847
+ identifyStateless(distinctId, properties, options) {
2848
+ this.wrap(() => {
2849
+ const payload = {
2850
+ ...this.buildPayload({
2851
+ distinct_id: distinctId,
2852
+ event: "$identify",
2853
+ properties
2854
+ })
2855
+ };
2856
+ this.enqueue("identify", payload, options);
2857
+ });
2858
+ }
2859
+ async identifyStatelessImmediate(distinctId, properties, options) {
2860
+ const payload = {
2861
+ ...this.buildPayload({
2862
+ distinct_id: distinctId,
2863
+ event: "$identify",
2864
+ properties
2865
+ })
2666
2866
  };
2667
- return context;
2867
+ await this.sendImmediate("identify", payload, options);
2668
2868
  }
2669
- };
2670
-
2671
- // ../../node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
2672
- var UNKNOWN_FUNCTION = "?";
2673
- function createFrame(platform, filename, func, lineno, colno) {
2674
- const frame = {
2675
- platform,
2676
- filename,
2677
- function: "<anonymous>" === func ? UNKNOWN_FUNCTION : func,
2678
- in_app: true
2679
- };
2680
- if (!isUndefined(lineno)) frame.lineno = lineno;
2681
- if (!isUndefined(colno)) frame.colno = colno;
2682
- return frame;
2683
- }
2684
-
2685
- // ../../node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
2686
- var extractSafariExtensionDetails = (func, filename) => {
2687
- const isSafariExtension = -1 !== func.indexOf("safari-extension");
2688
- const isSafariWebExtension = -1 !== func.indexOf("safari-web-extension");
2689
- return isSafariExtension || isSafariWebExtension ? [
2690
- -1 !== func.indexOf("@") ? func.split("@")[0] : UNKNOWN_FUNCTION,
2691
- isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`
2692
- ] : [
2693
- func,
2694
- filename
2695
- ];
2696
- };
2697
-
2698
- // ../../node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
2699
- var chromeRegexNoFnName = /^\s*at (\S+?)(?::(\d+))(?::(\d+))\s*$/i;
2700
- var chromeRegex = /^\s*at (?:(.+?\)(?: \[.+\])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
2701
- var chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
2702
- var chromeStackLineParser = (line, platform) => {
2703
- const noFnParts = chromeRegexNoFnName.exec(line);
2704
- if (noFnParts) {
2705
- const [, filename, line2, col] = noFnParts;
2706
- return createFrame(platform, filename, UNKNOWN_FUNCTION, +line2, +col);
2869
+ captureStateless(distinctId, event, properties, options) {
2870
+ this.wrap(() => {
2871
+ const payload = this.buildPayload({
2872
+ distinct_id: distinctId,
2873
+ event,
2874
+ properties
2875
+ });
2876
+ this.enqueue("capture", payload, options);
2877
+ });
2707
2878
  }
2708
- const parts = chromeRegex.exec(line);
2709
- if (parts) {
2710
- const isEval = parts[2] && 0 === parts[2].indexOf("eval");
2711
- if (isEval) {
2712
- const subMatch = chromeEvalRegex.exec(parts[2]);
2713
- if (subMatch) {
2714
- parts[2] = subMatch[1];
2715
- parts[3] = subMatch[2];
2716
- parts[4] = subMatch[3];
2717
- }
2718
- }
2719
- const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);
2720
- return createFrame(platform, filename, func, parts[3] ? +parts[3] : void 0, parts[4] ? +parts[4] : void 0);
2879
+ async captureStatelessImmediate(distinctId, event, properties, options) {
2880
+ const payload = this.buildPayload({
2881
+ distinct_id: distinctId,
2882
+ event,
2883
+ properties
2884
+ });
2885
+ await this.sendImmediate("capture", payload, options);
2721
2886
  }
2722
- };
2723
-
2724
- // ../../node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
2725
- var geckoREgex = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
2726
- var geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
2727
- var geckoStackLineParser = (line, platform) => {
2728
- const parts = geckoREgex.exec(line);
2729
- if (parts) {
2730
- const isEval = parts[3] && parts[3].indexOf(" > eval") > -1;
2731
- if (isEval) {
2732
- const subMatch = geckoEvalRegex.exec(parts[3]);
2733
- if (subMatch) {
2734
- parts[1] = parts[1] || "eval";
2735
- parts[3] = subMatch[1];
2736
- parts[4] = subMatch[2];
2737
- parts[5] = "";
2887
+ aliasStateless(alias, distinctId, properties, options) {
2888
+ this.wrap(() => {
2889
+ const payload = this.buildPayload({
2890
+ event: "$create_alias",
2891
+ distinct_id: distinctId,
2892
+ properties: {
2893
+ ...properties || {},
2894
+ distinct_id: distinctId,
2895
+ alias
2896
+ }
2897
+ });
2898
+ this.enqueue("alias", payload, options);
2899
+ });
2900
+ }
2901
+ async aliasStatelessImmediate(alias, distinctId, properties, options) {
2902
+ const payload = this.buildPayload({
2903
+ event: "$create_alias",
2904
+ distinct_id: distinctId,
2905
+ properties: {
2906
+ ...properties || {},
2907
+ distinct_id: distinctId,
2908
+ alias
2738
2909
  }
2739
- }
2740
- let filename = parts[3];
2741
- let func = parts[1] || UNKNOWN_FUNCTION;
2742
- [func, filename] = extractSafariExtensionDetails(func, filename);
2743
- return createFrame(platform, filename, func, parts[4] ? +parts[4] : void 0, parts[5] ? +parts[5] : void 0);
2910
+ });
2911
+ await this.sendImmediate("alias", payload, options);
2744
2912
  }
2745
- };
2746
-
2747
- // ../../node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
2748
- var winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:[-a-z]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
2749
- var winjsStackLineParser = (line, platform) => {
2750
- const parts = winjsRegex.exec(line);
2751
- return parts ? createFrame(platform, parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : void 0) : void 0;
2752
- };
2753
-
2754
- // ../../node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
2755
- var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
2756
- var opera10StackLineParser = (line, platform) => {
2757
- const parts = opera10Regex.exec(line);
2758
- return parts ? createFrame(platform, parts[2], parts[3] || UNKNOWN_FUNCTION, +parts[1]) : void 0;
2759
- };
2760
- var opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\(.*\))? in (.*):\s*$/i;
2761
- var opera11StackLineParser = (line, platform) => {
2762
- const parts = opera11Regex.exec(line);
2763
- return parts ? createFrame(platform, parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : void 0;
2764
- };
2765
-
2766
- // ../../node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
2767
- var FILENAME_MATCH = /^\s*[-]{4,}$/;
2768
- var FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
2769
- var nodeStackLineParser = (line, platform) => {
2770
- const lineMatch = line.match(FULL_MATCH);
2771
- if (lineMatch) {
2772
- let object;
2773
- let method;
2774
- let functionName;
2775
- let typeName;
2776
- let methodName;
2777
- if (lineMatch[1]) {
2778
- functionName = lineMatch[1];
2779
- let methodStart = functionName.lastIndexOf(".");
2780
- if ("." === functionName[methodStart - 1]) methodStart--;
2781
- if (methodStart > 0) {
2782
- object = functionName.slice(0, methodStart);
2783
- method = functionName.slice(methodStart + 1);
2784
- const objectEnd = object.indexOf(".Module");
2785
- if (objectEnd > 0) {
2786
- functionName = functionName.slice(objectEnd + 1);
2787
- object = object.slice(0, objectEnd);
2913
+ groupIdentifyStateless(groupType, groupKey, groupProperties, options, distinctId, eventProperties) {
2914
+ this.wrap(() => {
2915
+ const payload = this.buildPayload({
2916
+ distinct_id: distinctId || `$${groupType}_${groupKey}`,
2917
+ event: "$groupidentify",
2918
+ properties: {
2919
+ $group_type: groupType,
2920
+ $group_key: groupKey,
2921
+ $group_set: groupProperties || {},
2922
+ ...eventProperties || {}
2788
2923
  }
2924
+ });
2925
+ this.enqueue("capture", payload, options);
2926
+ });
2927
+ }
2928
+ async getRemoteConfig() {
2929
+ await this._initPromise;
2930
+ let host = this.host;
2931
+ if ("https://us.i.posthog.com" === host) host = "https://us-assets.i.posthog.com";
2932
+ else if ("https://eu.i.posthog.com" === host) host = "https://eu-assets.i.posthog.com";
2933
+ const url = `${host}/array/${this.apiKey}/config`;
2934
+ const fetchOptions = {
2935
+ method: "GET",
2936
+ headers: {
2937
+ ...this.getCustomHeaders(),
2938
+ "Content-Type": "application/json"
2789
2939
  }
2790
- typeName = void 0;
2791
- }
2792
- if (method) {
2793
- typeName = object;
2794
- methodName = method;
2795
- }
2796
- if ("<anonymous>" === method) {
2797
- methodName = void 0;
2798
- functionName = void 0;
2799
- }
2800
- if (void 0 === functionName) {
2801
- methodName = methodName || UNKNOWN_FUNCTION;
2802
- functionName = typeName ? `${typeName}.${methodName}` : methodName;
2803
- }
2804
- let filename = lineMatch[2]?.startsWith("file://") ? lineMatch[2].slice(7) : lineMatch[2];
2805
- const isNative = "native" === lineMatch[5];
2806
- if (filename?.match(/\/[A-Z]:/)) filename = filename.slice(1);
2807
- if (!filename && lineMatch[5] && !isNative) filename = lineMatch[5];
2808
- return {
2809
- filename: filename ? decodeURI(filename) : void 0,
2810
- module: void 0,
2811
- function: functionName,
2812
- lineno: _parseIntOrUndefined(lineMatch[3]),
2813
- colno: _parseIntOrUndefined(lineMatch[4]),
2814
- in_app: filenameIsInApp(filename || "", isNative),
2815
- platform
2816
2940
  };
2941
+ return this.fetchWithRetry(url, fetchOptions, {
2942
+ retryCount: 0
2943
+ }, this.remoteConfigRequestTimeoutMs).then((response) => response.json()).catch((error) => {
2944
+ this._logger.error("Remote config could not be loaded", error);
2945
+ this._events.emit("error", error);
2946
+ });
2817
2947
  }
2818
- if (line.match(FILENAME_MATCH)) return {
2819
- filename: line,
2820
- platform
2821
- };
2822
- };
2823
- function filenameIsInApp(filename, isNative = false) {
2824
- const isInternal = isNative || filename && !filename.startsWith("/") && !filename.match(/^[A-Z]:/) && !filename.startsWith(".") && !filename.match(/^[a-zA-Z]([a-zA-Z0-9.\-+])*:\/\//);
2825
- return !isInternal && void 0 !== filename && !filename.includes("node_modules/");
2826
- }
2827
- function _parseIntOrUndefined(input) {
2828
- return parseInt(input || "", 10) || void 0;
2829
- }
2830
-
2831
- // ../../node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
2832
- var WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
2833
- var STACKTRACE_FRAME_LIMIT = 50;
2834
- function reverseAndStripFrames(stack) {
2835
- if (!stack.length) return [];
2836
- const localStack = Array.from(stack);
2837
- localStack.reverse();
2838
- return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map((frame) => ({
2839
- ...frame,
2840
- filename: frame.filename || getLastStackFrame(localStack).filename,
2841
- function: frame.function || UNKNOWN_FUNCTION
2842
- }));
2843
- }
2844
- function getLastStackFrame(arr) {
2845
- return arr[arr.length - 1] || {};
2846
- }
2847
- function createDefaultStackParser() {
2848
- return createStackParser("web:javascript", chromeStackLineParser, geckoStackLineParser);
2849
- }
2850
- function createStackParser(platform, ...parsers) {
2851
- return (stack, skipFirstLines = 0) => {
2852
- const frames = [];
2853
- const lines = stack.split("\n");
2854
- for (let i2 = skipFirstLines; i2 < lines.length; i2++) {
2855
- const line = lines[i2];
2856
- if (line.length > 1024) continue;
2857
- const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, "$1") : line;
2858
- if (!cleanedLine.match(/\S*Error: /)) {
2859
- for (const parser of parsers) {
2860
- const frame = parser(cleanedLine, platform);
2861
- if (frame) {
2862
- frames.push(frame);
2863
- break;
2864
- }
2865
- }
2866
- if (frames.length >= STACKTRACE_FRAME_LIMIT) break;
2867
- }
2948
+ async getFlags(distinctId, groups = {}, personProperties = {}, groupProperties = {}, extraPayload = {}, fetchConfig = false) {
2949
+ await this._initPromise;
2950
+ const configParam = fetchConfig ? "&config=true" : "";
2951
+ const url = `${this.host}/flags/?v=2${configParam}`;
2952
+ const requestData = {
2953
+ token: this.apiKey,
2954
+ distinct_id: distinctId,
2955
+ groups,
2956
+ person_properties: personProperties,
2957
+ group_properties: groupProperties,
2958
+ ...extraPayload
2959
+ };
2960
+ if (personProperties.$device_id) requestData.$device_id = personProperties.$device_id;
2961
+ if (this.evaluationContexts && this.evaluationContexts.length > 0) requestData.evaluation_contexts = this.evaluationContexts;
2962
+ const fetchOptions = {
2963
+ method: "POST",
2964
+ headers: {
2965
+ ...this.getCustomHeaders(),
2966
+ "Content-Type": "application/json"
2967
+ },
2968
+ body: JSON.stringify(requestData)
2969
+ };
2970
+ this._logger.info("Flags URL", url);
2971
+ return this.fetchWithRetry(url, fetchOptions, {
2972
+ retryCount: 0
2973
+ }, this.featureFlagsRequestTimeoutMs).then((response) => response.json()).then((response) => ({
2974
+ success: true,
2975
+ response: normalizeFlagsResponse(response)
2976
+ })).catch((error) => {
2977
+ this._events.emit("error", error);
2978
+ return {
2979
+ success: false,
2980
+ error: this.categorizeRequestError(error)
2981
+ };
2982
+ });
2983
+ }
2984
+ categorizeRequestError(error) {
2985
+ if (error instanceof PostHogFetchHttpError) return {
2986
+ type: "api_error",
2987
+ statusCode: error.status
2988
+ };
2989
+ if (error instanceof PostHogFetchNetworkError) {
2990
+ const cause = error.error;
2991
+ if (cause instanceof Error && ("AbortError" === cause.name || "TimeoutError" === cause.name)) return {
2992
+ type: "timeout"
2993
+ };
2994
+ return {
2995
+ type: "connection_error"
2996
+ };
2868
2997
  }
2869
- return reverseAndStripFrames(frames);
2870
- };
2871
- }
2872
-
2873
- // ../../node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
2874
- var DOMExceptionCoercer = class {
2875
- match(err) {
2876
- return this.isDOMException(err) || this.isDOMError(err);
2998
+ return {
2999
+ type: "unknown_error"
3000
+ };
2877
3001
  }
2878
- coerce(err, ctx) {
2879
- const hasStack = isString(err.stack);
3002
+ async getFeatureFlagStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
3003
+ await this._initPromise;
3004
+ const flagDetailResponse = await this.getFeatureFlagDetailStateless(key, distinctId, groups, personProperties, groupProperties, disableGeoip);
3005
+ if (void 0 === flagDetailResponse) return {
3006
+ response: void 0,
3007
+ requestId: void 0
3008
+ };
3009
+ let response = getFeatureFlagValue(flagDetailResponse.response);
3010
+ if (void 0 === response) response = false;
2880
3011
  return {
2881
- type: this.getType(err),
2882
- value: this.getValue(err),
2883
- stack: hasStack ? err.stack : void 0,
2884
- cause: err.cause ? ctx.next(err.cause) : void 0,
2885
- synthetic: false
3012
+ response,
3013
+ requestId: flagDetailResponse.requestId
3014
+ };
3015
+ }
3016
+ async getFeatureFlagDetailStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
3017
+ await this._initPromise;
3018
+ const flagsResponse = await this.getFeatureFlagDetailsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, [
3019
+ key
3020
+ ]);
3021
+ if (void 0 === flagsResponse) return;
3022
+ const featureFlags = flagsResponse.flags;
3023
+ const flagDetail = featureFlags[key];
3024
+ return {
3025
+ response: flagDetail,
3026
+ requestId: flagsResponse.requestId,
3027
+ evaluatedAt: flagsResponse.evaluatedAt
2886
3028
  };
2887
3029
  }
2888
- getType(candidate) {
2889
- return this.isDOMError(candidate) ? "DOMError" : "DOMException";
2890
- }
2891
- getValue(err) {
2892
- const name = err.name || (this.isDOMError(err) ? "DOMError" : "DOMException");
2893
- const message = err.message ? `${name}: ${err.message}` : name;
2894
- return message;
2895
- }
2896
- isDOMException(err) {
2897
- return isBuiltin(err, "DOMException");
3030
+ async getFeatureFlagPayloadStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
3031
+ await this._initPromise;
3032
+ const payloads = await this.getFeatureFlagPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, [
3033
+ key
3034
+ ]);
3035
+ if (!payloads) return;
3036
+ const response = payloads[key];
3037
+ if (void 0 === response) return null;
3038
+ return response;
2898
3039
  }
2899
- isDOMError(err) {
2900
- return isBuiltin(err, "DOMError");
3040
+ async getFeatureFlagPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
3041
+ await this._initPromise;
3042
+ const payloads = (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate)).payloads;
3043
+ return payloads;
2901
3044
  }
2902
- };
2903
-
2904
- // ../../node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
2905
- var ErrorCoercer = class {
2906
- match(err) {
2907
- return isPlainError(err);
3045
+ async getFeatureFlagsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
3046
+ await this._initPromise;
3047
+ return await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate);
2908
3048
  }
2909
- coerce(err, ctx) {
3049
+ async getFeatureFlagsAndPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
3050
+ await this._initPromise;
3051
+ const featureFlagDetails = await this.getFeatureFlagDetailsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate);
3052
+ if (!featureFlagDetails) return {
3053
+ flags: void 0,
3054
+ payloads: void 0,
3055
+ requestId: void 0
3056
+ };
2910
3057
  return {
2911
- type: this.getType(err),
2912
- value: this.getMessage(err, ctx),
2913
- stack: this.getStack(err),
2914
- cause: err.cause ? ctx.next(err.cause) : void 0,
2915
- synthetic: false
3058
+ flags: featureFlagDetails.featureFlags,
3059
+ payloads: featureFlagDetails.featureFlagPayloads,
3060
+ requestId: featureFlagDetails.requestId
2916
3061
  };
2917
3062
  }
2918
- getType(err) {
2919
- return err.name || err.constructor.name;
2920
- }
2921
- getMessage(err, _ctx) {
2922
- const message = err.message;
2923
- if (message.error && "string" == typeof message.error.message) return String(message.error.message);
2924
- return String(message);
2925
- }
2926
- getStack(err) {
2927
- return err.stacktrace || err.stack || void 0;
3063
+ async getFeatureFlagDetailsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
3064
+ await this._initPromise;
3065
+ const extraPayload = {};
3066
+ if (disableGeoip ?? this.disableGeoip) extraPayload["geoip_disable"] = true;
3067
+ if (flagKeysToEvaluate) extraPayload["flag_keys_to_evaluate"] = flagKeysToEvaluate;
3068
+ const result = await this.getFlags(distinctId, groups, personProperties, groupProperties, extraPayload);
3069
+ if (!result.success) return;
3070
+ const flagsResponse = result.response;
3071
+ 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");
3072
+ if (flagsResponse.quotaLimited?.includes("feature_flags")) {
3073
+ 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");
3074
+ return {
3075
+ flags: {},
3076
+ featureFlags: {},
3077
+ featureFlagPayloads: {},
3078
+ requestId: flagsResponse?.requestId,
3079
+ quotaLimited: flagsResponse.quotaLimited
3080
+ };
3081
+ }
3082
+ return flagsResponse;
2928
3083
  }
2929
- };
2930
-
2931
- // ../../node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
2932
- var ErrorEventCoercer = class {
2933
- constructor() {
3084
+ async getSurveysStateless() {
3085
+ await this._initPromise;
3086
+ if (this.disabled) return [];
3087
+ if (true === this.disableSurveys) {
3088
+ this._logger.info("Loading surveys is disabled.");
3089
+ return [];
3090
+ }
3091
+ const url = `${this.host}/api/surveys/?token=${this.apiKey}`;
3092
+ const fetchOptions = {
3093
+ method: "GET",
3094
+ headers: {
3095
+ ...this.getCustomHeaders(),
3096
+ "Content-Type": "application/json"
3097
+ }
3098
+ };
3099
+ const response = await this.fetchWithRetry(url, fetchOptions).then((response2) => {
3100
+ if (200 !== response2.status || !response2.json) {
3101
+ const msg = `Surveys API could not be loaded: ${response2.status}`;
3102
+ const error = new Error(msg);
3103
+ this._logger.error(error);
3104
+ this._events.emit("error", new Error(msg));
3105
+ return;
3106
+ }
3107
+ return response2.json();
3108
+ }).catch((error) => {
3109
+ this._logger.error("Surveys API could not be loaded", error);
3110
+ this._events.emit("error", error);
3111
+ });
3112
+ const newSurveys = response?.surveys;
3113
+ if (newSurveys) this._logger.info("Surveys fetched from API: ", JSON.stringify(newSurveys));
3114
+ return newSurveys ?? [];
2934
3115
  }
2935
- match(err) {
2936
- return isErrorEvent(err) && void 0 != err.error;
3116
+ get props() {
3117
+ if (!this._props) this._props = this.getPersistedProperty(types_PostHogPersistedProperty.Props);
3118
+ return this._props || {};
2937
3119
  }
2938
- coerce(err, ctx) {
2939
- const exceptionLike = ctx.apply(err.error);
2940
- if (!exceptionLike) return {
2941
- type: "ErrorEvent",
2942
- value: err.message,
2943
- stack: ctx.syntheticException?.stack,
2944
- synthetic: true
2945
- };
2946
- return exceptionLike;
3120
+ set props(val) {
3121
+ this._props = val;
2947
3122
  }
2948
- };
2949
-
2950
- // ../../node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
2951
- var ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
2952
- var StringCoercer = class {
2953
- match(input) {
2954
- return "string" == typeof input;
3123
+ async register(properties) {
3124
+ this.wrap(() => {
3125
+ this.props = {
3126
+ ...this.props,
3127
+ ...properties
3128
+ };
3129
+ this.setPersistedProperty(types_PostHogPersistedProperty.Props, this.props);
3130
+ });
2955
3131
  }
2956
- coerce(input, ctx) {
2957
- const [type, value] = this.getInfos(input);
2958
- return {
2959
- type: type ?? "Error",
2960
- value: value ?? input,
2961
- stack: ctx.syntheticException?.stack,
2962
- synthetic: true
2963
- };
3132
+ async unregister(property) {
3133
+ this.wrap(() => {
3134
+ delete this.props[property];
3135
+ this.setPersistedProperty(types_PostHogPersistedProperty.Props, this.props);
3136
+ });
2964
3137
  }
2965
- getInfos(candidate) {
2966
- let type = "Error";
2967
- let value = candidate;
2968
- const groups = candidate.match(ERROR_TYPES_PATTERN);
2969
- if (groups) {
2970
- type = groups[1];
2971
- value = groups[2];
2972
- }
2973
- return [
2974
- type,
2975
- value
2976
- ];
3138
+ processBeforeEnqueue(message) {
3139
+ return message;
2977
3140
  }
2978
- };
2979
-
2980
- // ../../node_modules/@posthog/core/dist/error-tracking/types.mjs
2981
- var severityLevels = [
2982
- "fatal",
2983
- "error",
2984
- "warning",
2985
- "log",
2986
- "info",
2987
- "debug"
2988
- ];
2989
-
2990
- // ../../node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
2991
- function extractExceptionKeysForMessage(err, maxLength = 40) {
2992
- const keys = Object.keys(err);
2993
- keys.sort();
2994
- if (!keys.length) return "[object has no keys]";
2995
- for (let i2 = keys.length; i2 > 0; i2--) {
2996
- const serialized = keys.slice(0, i2).join(", ");
2997
- if (!(serialized.length > maxLength)) {
2998
- if (i2 === keys.length) return serialized;
2999
- return serialized.length <= maxLength ? serialized : `${serialized.slice(0, maxLength)}...`;
3000
- }
3141
+ async flushStorage() {
3001
3142
  }
3002
- return "";
3003
- }
3004
-
3005
- // ../../node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
3006
- var ObjectCoercer = class {
3007
- match(candidate) {
3008
- return "object" == typeof candidate && null !== candidate;
3143
+ enqueue(type, _message, options) {
3144
+ this.wrap(() => {
3145
+ if (this.optedOut) return void this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.optIn()");
3146
+ let message = this.prepareMessage(_message, options);
3147
+ message = this.processBeforeEnqueue(message);
3148
+ if (null === message) return;
3149
+ message = this.normalizeMessage(message);
3150
+ const queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
3151
+ if (queue.length >= this.maxQueueSize) {
3152
+ queue.shift();
3153
+ this._logger.info("Queue is full, the oldest event is dropped.");
3154
+ }
3155
+ queue.push({
3156
+ message
3157
+ });
3158
+ this.setPersistedProperty(types_PostHogPersistedProperty.Queue, queue);
3159
+ this._events.emit(type, message);
3160
+ if (queue.length >= this.flushAt) this.flushBackground();
3161
+ if (this.flushInterval && !this._flushTimer) this._flushTimer = safeSetTimeout(() => this.flushBackground(), this.flushInterval);
3162
+ });
3009
3163
  }
3010
- coerce(candidate, ctx) {
3011
- const errorProperty = this.getErrorPropertyFromObject(candidate);
3012
- if (errorProperty) return ctx.apply(errorProperty);
3013
- return {
3014
- type: this.getType(candidate),
3015
- value: this.getValue(candidate),
3016
- stack: ctx.syntheticException?.stack,
3017
- level: this.isSeverityLevel(candidate.level) ? candidate.level : "error",
3018
- synthetic: true
3164
+ async sendImmediate(type, _message, options) {
3165
+ if (this.disabled) return void this._logger.warn("The client is disabled");
3166
+ if (!this._isInitialized) await this._initPromise;
3167
+ if (this.optedOut) return void this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.optIn()");
3168
+ let message = this.prepareMessage(_message, options);
3169
+ message = this.processBeforeEnqueue(message);
3170
+ if (null === message) return;
3171
+ message = this.normalizeMessage(message);
3172
+ const data = {
3173
+ api_key: this.apiKey,
3174
+ batch: [
3175
+ message
3176
+ ],
3177
+ sent_at: currentISOTime()
3178
+ };
3179
+ if (this.historicalMigration) data.historical_migration = true;
3180
+ const payload = JSON.stringify(data);
3181
+ const url = `${this.host}/batch/`;
3182
+ const gzippedPayload = this.disableCompression ? null : await gzipCompress(payload, this.isDebug);
3183
+ const fetchOptions = {
3184
+ method: "POST",
3185
+ headers: {
3186
+ ...this.getCustomHeaders(),
3187
+ "Content-Type": "application/json",
3188
+ ...null !== gzippedPayload && {
3189
+ "Content-Encoding": "gzip"
3190
+ }
3191
+ },
3192
+ body: gzippedPayload || payload
3019
3193
  };
3020
- }
3021
- getType(err) {
3022
- return isEvent(err) ? err.constructor.name : "Error";
3023
- }
3024
- getValue(err) {
3025
- if ("name" in err && "string" == typeof err.name) {
3026
- let message = `'${err.name}' captured as exception`;
3027
- if ("message" in err && "string" == typeof err.message) message += ` with message: '${err.message}'`;
3028
- return message;
3194
+ try {
3195
+ const response = await this.fetchWithRetry(url, fetchOptions);
3196
+ await response.body?.cancel()?.catch(() => {
3197
+ });
3198
+ } catch (err) {
3199
+ this._events.emit("error", err);
3029
3200
  }
3030
- if ("message" in err && "string" == typeof err.message) return err.message;
3031
- const className = this.getObjectClassName(err);
3032
- const keys = extractExceptionKeysForMessage(err);
3033
- return `${className && "Object" !== className ? `'${className}'` : "Object"} captured as exception with keys: ${keys}`;
3034
3201
  }
3035
- isSeverityLevel(x) {
3036
- return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;
3202
+ normalizeMessage(message) {
3203
+ const { type: _type, library, library_version, ...sanitizedMessage } = message;
3204
+ let properties = isPostHogEventProperties(sanitizedMessage.properties) ? sanitizedMessage.properties : void 0;
3205
+ if (void 0 !== library && properties?.$lib === void 0) properties = {
3206
+ ...properties || {},
3207
+ $lib: library
3208
+ };
3209
+ if (void 0 !== library_version && properties?.$lib_version === void 0) properties = {
3210
+ ...properties || {},
3211
+ $lib_version: library_version
3212
+ };
3213
+ if (properties) sanitizedMessage.properties = properties;
3214
+ sanitizedMessage.uuid = getEventUuid(sanitizedMessage.uuid, uuidv7);
3215
+ return sanitizedMessage;
3037
3216
  }
3038
- getErrorPropertyFromObject(obj) {
3039
- for (const prop in obj) if (Object.prototype.hasOwnProperty.call(obj, prop)) {
3040
- const value = obj[prop];
3041
- if (isError(value)) return value;
3217
+ prepareMessage(_message, options) {
3218
+ const message = {
3219
+ ..._message,
3220
+ timestamp: options?.timestamp ? options?.timestamp : currentISOTime(),
3221
+ uuid: getEventUuid(options?.uuid, uuidv7)
3222
+ };
3223
+ const addGeoipDisableProperty = options?.disableGeoip ?? this.disableGeoip;
3224
+ if (addGeoipDisableProperty) {
3225
+ if (!isPostHogEventProperties(message.properties)) message.properties = {};
3226
+ message.properties["$geoip_disable"] = true;
3042
3227
  }
3043
- }
3044
- getObjectClassName(obj) {
3045
- try {
3046
- const prototype = Object.getPrototypeOf(obj);
3047
- return prototype ? prototype.constructor.name : void 0;
3048
- } catch (e) {
3049
- return;
3228
+ if (message.distinctId) {
3229
+ message.distinct_id = message.distinctId;
3230
+ delete message.distinctId;
3050
3231
  }
3232
+ return message;
3051
3233
  }
3052
- };
3053
-
3054
- // ../../node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
3055
- var EventCoercer = class {
3056
- match(err) {
3057
- return isEvent(err);
3058
- }
3059
- coerce(evt, ctx) {
3060
- const constructorName = evt.constructor.name;
3061
- return {
3062
- type: constructorName,
3063
- value: `${constructorName} captured as exception with keys: ${extractExceptionKeysForMessage(evt)}`,
3064
- stack: ctx.syntheticException?.stack,
3065
- synthetic: true
3066
- };
3234
+ clearFlushTimer() {
3235
+ if (this._flushTimer) {
3236
+ clearTimeout(this._flushTimer);
3237
+ this._flushTimer = void 0;
3238
+ }
3067
3239
  }
3068
- };
3069
-
3070
- // ../../node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
3071
- var PrimitiveCoercer = class {
3072
- match(candidate) {
3073
- return isPrimitive(candidate);
3240
+ flushBackground() {
3241
+ this.flush().catch(async (err) => {
3242
+ await logFlushError(err);
3243
+ });
3074
3244
  }
3075
- coerce(value, ctx) {
3076
- return {
3077
- type: "Error",
3078
- value: `Primitive value captured as exception: ${String(value)}`,
3079
- stack: ctx.syntheticException?.stack,
3080
- synthetic: true
3081
- };
3245
+ async flush() {
3246
+ if (this.disabled) return;
3247
+ const nextFlushPromise = allSettled([
3248
+ this.flushPromise
3249
+ ]).then(() => this._flush());
3250
+ this.flushPromise = nextFlushPromise;
3251
+ this.addPendingPromise(nextFlushPromise);
3252
+ allSettled([
3253
+ nextFlushPromise
3254
+ ]).then(() => {
3255
+ if (this.flushPromise === nextFlushPromise) this.flushPromise = null;
3256
+ });
3257
+ return nextFlushPromise;
3082
3258
  }
3083
- };
3084
-
3085
- // ../../node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
3086
- var PromiseRejectionEventCoercer = class {
3087
- match(err) {
3088
- return isBuiltin(err, "PromiseRejectionEvent") || this.isCustomEventWrappingRejection(err);
3259
+ getCustomHeaders() {
3260
+ const customUserAgent = this.getCustomUserAgent();
3261
+ const headers = {};
3262
+ if (customUserAgent && "" !== customUserAgent) headers["User-Agent"] = customUserAgent;
3263
+ return headers;
3089
3264
  }
3090
- isCustomEventWrappingRejection(err) {
3091
- if (!isEvent(err)) return false;
3092
- try {
3093
- const detail = err.detail;
3094
- return null != detail && "object" == typeof detail && "reason" in detail;
3095
- } catch {
3096
- return false;
3265
+ async _flush() {
3266
+ this.clearFlushTimer();
3267
+ await this._initPromise;
3268
+ let queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
3269
+ if (!queue.length) return;
3270
+ const sentMessages = [];
3271
+ const originalQueueLength = queue.length;
3272
+ while (queue.length > 0 && sentMessages.length < originalQueueLength) {
3273
+ const batchItems = queue.slice(0, this.maxBatchSize);
3274
+ const batchMessages = batchItems.map((item) => void 0 === item.message ? item.message : this.normalizeMessage(item.message));
3275
+ const persistQueueChange = async () => {
3276
+ const refreshedQueue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
3277
+ const newQueue = refreshedQueue.slice(batchItems.length);
3278
+ this.setPersistedProperty(types_PostHogPersistedProperty.Queue, newQueue);
3279
+ queue = newQueue;
3280
+ await this.flushStorage();
3281
+ };
3282
+ const data = {
3283
+ api_key: this.apiKey,
3284
+ batch: batchMessages,
3285
+ sent_at: currentISOTime()
3286
+ };
3287
+ if (this.historicalMigration) data.historical_migration = true;
3288
+ const payload = JSON.stringify(data);
3289
+ const url = `${this.host}/batch/`;
3290
+ const gzippedPayload = this.disableCompression ? null : await gzipCompress(payload, this.isDebug);
3291
+ const fetchOptions = {
3292
+ method: "POST",
3293
+ headers: {
3294
+ ...this.getCustomHeaders(),
3295
+ "Content-Type": "application/json",
3296
+ ...null !== gzippedPayload && {
3297
+ "Content-Encoding": "gzip"
3298
+ }
3299
+ },
3300
+ body: gzippedPayload || payload
3301
+ };
3302
+ const retryOptions = {
3303
+ retryCheck: (err) => {
3304
+ if (isPostHogFetchContentTooLargeError(err)) return false;
3305
+ return isPostHogFetchError(err);
3306
+ }
3307
+ };
3308
+ try {
3309
+ const response = await this.fetchWithRetry(url, fetchOptions, retryOptions);
3310
+ await response.body?.cancel()?.catch(() => {
3311
+ });
3312
+ } catch (err) {
3313
+ if (isPostHogFetchContentTooLargeError(err) && batchMessages.length > 1) {
3314
+ this.maxBatchSize = Math.max(1, Math.floor(batchMessages.length / 2));
3315
+ this._logger.warn(`Received 413 when sending batch of size ${batchMessages.length}, reducing batch size to ${this.maxBatchSize}`);
3316
+ continue;
3317
+ }
3318
+ if (!(err instanceof PostHogFetchNetworkError)) await persistQueueChange();
3319
+ this._events.emit("error", err);
3320
+ throw err;
3321
+ }
3322
+ await persistQueueChange();
3323
+ sentMessages.push(...batchMessages);
3097
3324
  }
3325
+ this._events.emit("flush", sentMessages);
3098
3326
  }
3099
- coerce(err, ctx) {
3100
- const reason = this.getUnhandledRejectionReason(err);
3101
- if (isPrimitive(reason)) return {
3102
- type: "UnhandledRejection",
3103
- value: `Non-Error promise rejection captured with value: ${String(reason)}`,
3104
- stack: ctx.syntheticException?.stack,
3105
- synthetic: true
3327
+ async _sendLogsBatch(payload) {
3328
+ if (this.disabled) return {
3329
+ kind: "fatal",
3330
+ error: new Error("The client is disabled")
3331
+ };
3332
+ const serialized = JSON.stringify(payload);
3333
+ const url = `${this.host}/i/v1/logs?token=${encodeURIComponent(this.apiKey)}`;
3334
+ const gzippedPayload = this.disableCompression ? null : await gzipCompress(serialized, this.isDebug);
3335
+ const fetchOptions = {
3336
+ method: "POST",
3337
+ headers: {
3338
+ ...this.getCustomHeaders(),
3339
+ "Content-Type": "application/json",
3340
+ ...null !== gzippedPayload && {
3341
+ "Content-Encoding": "gzip"
3342
+ }
3343
+ },
3344
+ body: gzippedPayload || serialized
3106
3345
  };
3107
- return ctx.apply(reason);
3108
- }
3109
- getUnhandledRejectionReason(error) {
3110
3346
  try {
3111
- if ("reason" in error) return error.reason;
3112
- if ("detail" in error && null != error.detail && "object" == typeof error.detail && "reason" in error.detail) return error.detail.reason;
3113
- } catch {
3114
- }
3115
- return error;
3116
- }
3117
- };
3118
-
3119
- // ../../node_modules/@posthog/core/dist/error-tracking/utils.mjs
3120
- var ReduceableCache = class {
3121
- constructor(_maxSize) {
3122
- this._maxSize = _maxSize;
3123
- this._cache = /* @__PURE__ */ new Map();
3124
- }
3125
- get(key) {
3126
- const value = this._cache.get(key);
3127
- if (void 0 === value) return;
3128
- this._cache.delete(key);
3129
- this._cache.set(key, value);
3130
- return value;
3131
- }
3132
- set(key, value) {
3133
- this._cache.set(key, value);
3134
- }
3135
- reduce() {
3136
- while (this._cache.size >= this._maxSize) {
3137
- const value = this._cache.keys().next().value;
3138
- if (value) this._cache.delete(value);
3347
+ await this.fetchWithRetry(url, fetchOptions, {
3348
+ retryCheck: (err) => {
3349
+ if (isPostHogFetchContentTooLargeError(err)) return false;
3350
+ return isPostHogFetchError(err);
3351
+ }
3352
+ });
3353
+ return {
3354
+ kind: "ok"
3355
+ };
3356
+ } catch (err) {
3357
+ if (isPostHogFetchContentTooLargeError(err)) return {
3358
+ kind: "too-large"
3359
+ };
3360
+ if (err instanceof PostHogFetchNetworkError) return {
3361
+ kind: "retry-later",
3362
+ error: err
3363
+ };
3364
+ return {
3365
+ kind: "fatal",
3366
+ error: err
3367
+ };
3139
3368
  }
3140
3369
  }
3141
- };
3142
-
3143
- // ../../node_modules/@posthog/core/dist/error-tracking/exception-steps.mjs
3144
- var EXCEPTION_STEP_INTERNAL_FIELDS = {
3145
- MESSAGE: "$message",
3146
- TIMESTAMP: "$timestamp"
3147
- };
3148
- var RESERVED_EXCEPTION_STEP_KEYS = /* @__PURE__ */ new Set([
3149
- EXCEPTION_STEP_INTERNAL_FIELDS.MESSAGE,
3150
- EXCEPTION_STEP_INTERNAL_FIELDS.TIMESTAMP
3151
- ]);
3152
- var DEFAULT_EXCEPTION_STEPS_CONFIG = {
3153
- enabled: true,
3154
- max_bytes: 32768
3155
- };
3156
- function resolveExceptionStepsConfig(config) {
3157
- if (!config) return {
3158
- ...DEFAULT_EXCEPTION_STEPS_CONFIG
3159
- };
3160
- return {
3161
- enabled: config.enabled ?? DEFAULT_EXCEPTION_STEPS_CONFIG.enabled,
3162
- max_bytes: normalizePositiveInteger(config.max_bytes, DEFAULT_EXCEPTION_STEPS_CONFIG.max_bytes)
3163
- };
3164
- }
3165
- function stripReservedExceptionStepFields(properties) {
3166
- if (!properties) return {
3167
- sanitizedProperties: {},
3168
- droppedKeys: []
3169
- };
3170
- const droppedKeys = [];
3171
- const sanitizedProperties = Object.keys(properties).reduce((acc, key) => {
3172
- if (RESERVED_EXCEPTION_STEP_KEYS.has(key)) {
3173
- droppedKeys.push(key);
3174
- return acc;
3370
+ async fetchWithRetry(url, options, retryOptions, requestTimeout) {
3371
+ const body = options.body ? options.body : "";
3372
+ let reqByteLength = -1;
3373
+ try {
3374
+ reqByteLength = body instanceof Blob ? body.size : Buffer.byteLength(body, STRING_FORMAT);
3375
+ } catch {
3376
+ if (body instanceof Blob) reqByteLength = body.size;
3377
+ else {
3378
+ const encoded = new TextEncoder().encode(body);
3379
+ reqByteLength = encoded.length;
3380
+ }
3175
3381
  }
3176
- acc[key] = properties[key];
3177
- return acc;
3178
- }, {});
3179
- return {
3180
- sanitizedProperties,
3181
- droppedKeys
3182
- };
3183
- }
3184
- var ExceptionStepsBuffer = class {
3185
- constructor(config) {
3186
- this._entries = [];
3187
- this._totalBytes = 0;
3188
- this._config = resolveExceptionStepsConfig(config);
3189
- }
3190
- setConfig(config) {
3191
- this._config = resolveExceptionStepsConfig(config);
3192
- this._trimToMaxBytes();
3193
- }
3194
- add(step) {
3195
- const serialized = normalizeAndSerializeStep(step);
3196
- if (!serialized) return;
3197
- const bytes = getUtf8ByteLength(serialized.json);
3198
- if (bytes > this._config.max_bytes) return;
3199
- this._entries.push({
3200
- step: serialized.step,
3201
- bytes
3382
+ return await retriable(async () => {
3383
+ const ctrl = new AbortController();
3384
+ const timeoutMs = requestTimeout ?? this.requestTimeout;
3385
+ const timer = safeSetTimeout(() => ctrl.abort(), timeoutMs);
3386
+ let res = null;
3387
+ try {
3388
+ res = await this.fetch(url, {
3389
+ signal: ctrl.signal,
3390
+ ...options
3391
+ });
3392
+ } catch (e) {
3393
+ throw new PostHogFetchNetworkError(e);
3394
+ } finally {
3395
+ clearTimeout(timer);
3396
+ }
3397
+ const isNoCors = "no-cors" === options.mode;
3398
+ if (!isNoCors && (res.status < 200 || res.status >= 400)) throw new PostHogFetchHttpError(res, reqByteLength);
3399
+ return res;
3400
+ }, {
3401
+ ...this._retryOptions,
3402
+ ...retryOptions
3202
3403
  });
3203
- this._totalBytes += bytes;
3204
- this._trimToMaxBytes();
3205
- }
3206
- getAttachable() {
3207
- return this._entries.map((e) => e.step);
3208
- }
3209
- clear() {
3210
- this._entries = [];
3211
- this._totalBytes = 0;
3212
- }
3213
- size() {
3214
- return this._entries.length;
3215
3404
  }
3216
- _trimToMaxBytes() {
3217
- while (this._totalBytes > this._config.max_bytes && this._entries.length > 0) {
3218
- const evicted = this._entries.shift();
3219
- if (evicted) this._totalBytes -= evicted.bytes;
3220
- }
3221
- }
3222
- };
3223
- function normalizePositiveInteger(input, fallback) {
3224
- if (!isNumber(input) || input === 1 / 0 || input === -1 / 0) return fallback;
3225
- const normalized = Math.floor(input);
3226
- if (normalized < 0) return fallback;
3227
- return normalized;
3228
- }
3229
- function normalizeAndSerializeStep(step) {
3230
- const json = safeStringify(step);
3231
- if (!json) return;
3232
- try {
3233
- const parsed = JSON.parse(json);
3234
- if (!isObject(parsed)) return;
3235
- const parsedStep = parsed;
3236
- const message = parsedStep[EXCEPTION_STEP_INTERNAL_FIELDS.MESSAGE];
3237
- const timestamp = parsedStep[EXCEPTION_STEP_INTERNAL_FIELDS.TIMESTAMP];
3238
- if (!isString(message) || 0 === message.trim().length) return;
3239
- if (!isString(timestamp) && !isNumber(timestamp)) return;
3240
- return {
3241
- step: parsedStep,
3242
- json
3405
+ async _shutdown(shutdownTimeoutMs = 3e4) {
3406
+ await this._initPromise;
3407
+ let hasTimedOut = false;
3408
+ this.clearFlushTimer();
3409
+ if (this.disabled) return;
3410
+ const doShutdown = async () => {
3411
+ try {
3412
+ await this.promiseQueue.join();
3413
+ while (true) {
3414
+ const queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
3415
+ if (0 === queue.length) break;
3416
+ await this.flush();
3417
+ if (hasTimedOut) break;
3418
+ }
3419
+ } catch (e) {
3420
+ if (!isPostHogFetchError(e)) throw e;
3421
+ await logFlushError(e);
3422
+ }
3243
3423
  };
3244
- } catch {
3245
- return;
3424
+ let timeoutHandle;
3425
+ try {
3426
+ return await Promise.race([
3427
+ new Promise((_, reject) => {
3428
+ timeoutHandle = safeSetTimeout(() => {
3429
+ this._logger.error("Timed out while shutting down PostHog");
3430
+ hasTimedOut = true;
3431
+ reject("Timeout while shutting down PostHog. Some events may not have been sent.");
3432
+ }, shutdownTimeoutMs);
3433
+ }),
3434
+ doShutdown()
3435
+ ]);
3436
+ } finally {
3437
+ clearTimeout(timeoutHandle);
3438
+ }
3246
3439
  }
3247
- }
3248
- function safeStringify(value) {
3249
- const seen = /* @__PURE__ */ new WeakSet();
3250
- try {
3251
- return JSON.stringify(value, (_key, replacementValue) => {
3252
- if ("bigint" == typeof replacementValue) return replacementValue.toString();
3253
- if ("function" == typeof replacementValue || "symbol" == typeof replacementValue) return;
3254
- if (replacementValue instanceof Date) return replacementValue.toISOString();
3255
- if (replacementValue instanceof Error) return {
3256
- name: replacementValue.name,
3257
- message: replacementValue.message,
3258
- stack: replacementValue.stack
3259
- };
3260
- if (replacementValue && "object" == typeof replacementValue) {
3261
- if (seen.has(replacementValue)) return "[Circular]";
3262
- seen.add(replacementValue);
3263
- }
3264
- return replacementValue;
3440
+ async shutdown(shutdownTimeoutMs = 3e4) {
3441
+ 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");
3442
+ else this.shutdownPromise = this._shutdown(shutdownTimeoutMs).finally(() => {
3443
+ this.shutdownPromise = null;
3265
3444
  });
3266
- } catch {
3267
- return;
3445
+ return this.shutdownPromise;
3268
3446
  }
3269
- }
3270
- function getUtf8ByteLength(value) {
3271
- if ("undefined" != typeof TextEncoder) return new TextEncoder().encode(value).length;
3272
- const encoded = encodeURIComponent(value);
3273
- let byteLength = 0;
3274
- for (let i2 = 0; i2 < encoded.length; i2++) if ("%" === encoded[i2]) {
3275
- byteLength += 1;
3276
- i2 += 2;
3277
- } else byteLength += 1;
3278
- return byteLength;
3279
- }
3447
+ };
3280
3448
 
3281
3449
  // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
3282
3450
  import { createReadStream } from "node:fs";
@@ -3450,137 +3618,38 @@ function emplace(map, key, contents) {
3450
3618
  }
3451
3619
  return value;
3452
3620
  }
3453
- function snipLine(line, colno) {
3454
- let newLine = line;
3455
- const lineLength = newLine.length;
3456
- if (lineLength <= 150) return newLine;
3457
- if (colno > lineLength) colno = lineLength;
3458
- let start = Math.max(colno - 60, 0);
3459
- if (start < 5) start = 0;
3460
- let end = Math.min(start + 140, lineLength);
3461
- if (end > lineLength - 5) end = lineLength;
3462
- if (end === lineLength) start = Math.max(end - 140, 0);
3463
- newLine = newLine.slice(start, end);
3464
- if (start > 0) newLine = `...${newLine}`;
3465
- if (end < lineLength) newLine += "...";
3466
- return newLine;
3467
- }
3468
-
3469
- // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs
3470
- import { isAbsolute as isAbsolute2, relative, sep as sep2 } from "path";
3471
- function createRelativePathModifier(basePath = process.cwd()) {
3472
- const isWindows = "\\" === sep2;
3473
- const toUnix = (p) => isWindows ? p.replace(/\\/g, "/") : p;
3474
- const normalizedBase = toUnix(basePath);
3475
- return async (frames) => {
3476
- for (const frame of frames) if (!(!frame.filename || frame.filename.startsWith("node:") || frame.filename.startsWith("data:"))) {
3477
- if (isAbsolute2(frame.filename)) frame.filename = toUnix(relative(normalizedBase, toUnix(frame.filename)));
3478
- }
3479
- return frames;
3480
- };
3481
- }
3482
-
3483
- // ../../node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs
3484
- function makeUncaughtExceptionHandler(captureFn, onFatalFn) {
3485
- let calledFatalError = false;
3486
- return Object.assign((error) => {
3487
- const userProvidedListenersCount = global.process.listeners("uncaughtException").filter((listener) => "domainUncaughtExceptionClear" !== listener.name && true !== listener._posthogErrorHandler).length;
3488
- const processWouldExit = 0 === userProvidedListenersCount;
3489
- captureFn(error, {
3490
- mechanism: {
3491
- type: "onuncaughtexception",
3492
- handled: false
3493
- }
3494
- });
3495
- if (!calledFatalError && processWouldExit) {
3496
- calledFatalError = true;
3497
- onFatalFn(error);
3498
- }
3499
- }, {
3500
- _posthogErrorHandler: true
3501
- });
3502
- }
3503
- function addUncaughtExceptionListener(captureFn, onFatalFn) {
3504
- globalThis.process?.on("uncaughtException", makeUncaughtExceptionHandler(captureFn, onFatalFn));
3505
- }
3506
- function addUnhandledRejectionListener(captureFn) {
3507
- globalThis.process?.on("unhandledRejection", (reason) => captureFn(reason, {
3508
- mechanism: {
3509
- type: "onunhandledrejection",
3510
- handled: false
3511
- }
3512
- }));
3621
+ function snipLine(line, colno) {
3622
+ let newLine = line;
3623
+ const lineLength = newLine.length;
3624
+ if (lineLength <= 150) return newLine;
3625
+ if (colno > lineLength) colno = lineLength;
3626
+ let start = Math.max(colno - 60, 0);
3627
+ if (start < 5) start = 0;
3628
+ let end = Math.min(start + 140, lineLength);
3629
+ if (end > lineLength - 5) end = lineLength;
3630
+ if (end === lineLength) start = Math.max(end - 140, 0);
3631
+ newLine = newLine.slice(start, end);
3632
+ if (start > 0) newLine = `...${newLine}`;
3633
+ if (end < lineLength) newLine += "...";
3634
+ return newLine;
3513
3635
  }
3514
3636
 
3515
- // ../../node_modules/posthog-node/dist/extensions/error-tracking/index.mjs
3516
- var SHUTDOWN_TIMEOUT = 2e3;
3517
- var ErrorTracking = class _ErrorTracking {
3518
- constructor(client2, options, _logger) {
3519
- this.client = client2;
3520
- this._exceptionAutocaptureEnabled = options.enableExceptionAutocapture || false;
3521
- this._logger = _logger;
3522
- this._rateLimiter = new BucketedRateLimiter({
3523
- refillRate: 1,
3524
- bucketSize: 10,
3525
- refillInterval: 1e4,
3526
- _logger: this._logger
3527
- });
3528
- this.startAutocaptureIfEnabled();
3529
- }
3530
- static isPreviouslyCapturedError(x) {
3531
- return isObject(x) && "__posthog_previously_captured_error" in x && true === x.__posthog_previously_captured_error;
3532
- }
3533
- static async buildEventMessage(error, hint, distinctId, additionalProperties) {
3534
- const properties = {
3535
- ...additionalProperties
3536
- };
3537
- const exceptionProperties = this.errorPropertiesBuilder.buildFromUnknown(error, hint);
3538
- exceptionProperties.$exception_list = await this.errorPropertiesBuilder.modifyFrames(exceptionProperties.$exception_list);
3539
- return {
3540
- event: "$exception",
3541
- distinctId,
3542
- properties: {
3543
- ...exceptionProperties,
3544
- ...properties
3545
- },
3546
- _originatedFromCaptureException: true
3547
- };
3548
- }
3549
- startAutocaptureIfEnabled() {
3550
- if (this.isEnabled()) {
3551
- addUncaughtExceptionListener(this.onException.bind(this), this.onFatalError.bind(this));
3552
- addUnhandledRejectionListener(this.onException.bind(this));
3637
+ // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs
3638
+ import { isAbsolute as isAbsolute2, relative, sep as sep2 } from "path";
3639
+ function createRelativePathModifier(basePath = process.cwd()) {
3640
+ const isWindows = "\\" === sep2;
3641
+ const toUnix = (p) => isWindows ? p.replace(/\\/g, "/") : p;
3642
+ const normalizedBase = toUnix(basePath);
3643
+ return async (frames) => {
3644
+ for (const frame of frames) if (!(!frame.filename || frame.filename.startsWith("node:") || frame.filename.startsWith("data:"))) {
3645
+ if (isAbsolute2(frame.filename)) frame.filename = toUnix(relative(normalizedBase, toUnix(frame.filename)));
3553
3646
  }
3554
- }
3555
- onException(exception, hint) {
3556
- this.client.addPendingPromise((async () => {
3557
- if (!_ErrorTracking.isPreviouslyCapturedError(exception)) {
3558
- const eventMessage = await _ErrorTracking.buildEventMessage(exception, hint);
3559
- const exceptionProperties = eventMessage.properties;
3560
- const exceptionType = exceptionProperties?.$exception_list[0]?.type ?? "Exception";
3561
- const isRateLimited = this._rateLimiter.consumeRateLimit(exceptionType);
3562
- if (isRateLimited) return void this._logger.info("Skipping exception capture because of client rate limiting.", {
3563
- exception: exceptionType
3564
- });
3565
- return this.client.capture(eventMessage);
3566
- }
3567
- })());
3568
- }
3569
- async onFatalError(exception) {
3570
- console.error(exception);
3571
- await this.client.shutdown(SHUTDOWN_TIMEOUT);
3572
- process.exit(1);
3573
- }
3574
- isEnabled() {
3575
- return !this.client.isDisabled && this._exceptionAutocaptureEnabled;
3576
- }
3577
- shutdown() {
3578
- this._rateLimiter.stop();
3579
- }
3580
- };
3647
+ return frames;
3648
+ };
3649
+ }
3581
3650
 
3582
3651
  // ../../node_modules/posthog-node/dist/version.mjs
3583
- var version = "5.35.0";
3652
+ var version = "5.38.6";
3584
3653
 
3585
3654
  // ../../node_modules/posthog-node/dist/types.mjs
3586
3655
  var FeatureFlagError2 = {
@@ -3732,20 +3801,21 @@ var ClientError = class _ClientError extends Error {
3732
3801
  Object.setPrototypeOf(this, _ClientError.prototype);
3733
3802
  }
3734
3803
  };
3804
+ function setCustomErrorPrototype(error, constructor) {
3805
+ error.name = constructor.name;
3806
+ Error.captureStackTrace(error, constructor);
3807
+ Object.setPrototypeOf(error, constructor.prototype);
3808
+ }
3735
3809
  var InconclusiveMatchError = class _InconclusiveMatchError extends Error {
3736
3810
  constructor(message) {
3737
3811
  super(message);
3738
- this.name = this.constructor.name;
3739
- Error.captureStackTrace(this, this.constructor);
3740
- Object.setPrototypeOf(this, _InconclusiveMatchError.prototype);
3812
+ setCustomErrorPrototype(this, _InconclusiveMatchError);
3741
3813
  }
3742
3814
  };
3743
3815
  var RequiresServerEvaluation = class _RequiresServerEvaluation extends Error {
3744
3816
  constructor(message) {
3745
3817
  super(message);
3746
- this.name = this.constructor.name;
3747
- Error.captureStackTrace(this, this.constructor);
3748
- Object.setPrototypeOf(this, _RequiresServerEvaluation.prototype);
3818
+ setCustomErrorPrototype(this, _RequiresServerEvaluation);
3749
3819
  }
3750
3820
  };
3751
3821
  var FeatureFlagsPoller = class {
@@ -3937,6 +4007,7 @@ var FeatureFlagsPoller = class {
3937
4007
  const flagFilters = flag.filters || {};
3938
4008
  const flagConditions = flagFilters.groups || [];
3939
4009
  const flagAggregation = flagFilters.aggregation_group_type_index;
4010
+ const earlyExitEnabled = flagFilters.early_exit ?? false;
3940
4011
  const { groups, groupProperties } = evaluationContext;
3941
4012
  let isInconclusive = false;
3942
4013
  let result;
@@ -3959,12 +4030,14 @@ var FeatureFlagsPoller = class {
3959
4030
  effectiveBucketingValue = groups[groupName];
3960
4031
  }
3961
4032
  }
3962
- if (await this.isConditionMatch(flag, effectiveBucketingValue, condition, effectiveProperties, evaluationContext)) {
4033
+ const matchResult = await this.isConditionMatch(flag, effectiveBucketingValue, condition, effectiveProperties, evaluationContext);
4034
+ if ("match" === matchResult) {
3963
4035
  const variantOverride = condition.variant;
3964
4036
  const flagVariants = flagFilters.multivariate?.variants || [];
3965
4037
  result = variantOverride && flagVariants.some((variant) => variant.key === variantOverride) ? variantOverride : await this.getMatchingVariant(flag, effectiveBucketingValue) || true;
3966
4038
  break;
3967
4039
  }
4040
+ if (earlyExitEnabled && "out_of_rollout_bound" === matchResult) return false;
3968
4041
  } catch (e) {
3969
4042
  if (e instanceof RequiresServerEvaluation) throw e;
3970
4043
  if (e instanceof InconclusiveMatchError) isInconclusive = true;
@@ -3984,12 +4057,12 @@ var FeatureFlagsPoller = class {
3984
4057
  const propertyType = prop.type;
3985
4058
  let matches2 = false;
3986
4059
  matches2 = "cohort" === propertyType ? await matchCohort(prop, properties, this.cohorts, this.debugMode, (depProp) => this.evaluateFlagDependency(depProp, properties, evaluationContext)) : "flag" === propertyType ? await this.evaluateFlagDependency(prop, properties, evaluationContext) : matchProperty(prop, properties, warnFunction);
3987
- if (!matches2) return false;
4060
+ if (!matches2) return "no_match";
3988
4061
  }
3989
- if (void 0 == rolloutPercentage) return true;
4062
+ if (void 0 == rolloutPercentage) return "match";
3990
4063
  }
3991
- if (void 0 != rolloutPercentage && await _hash(flag.key, bucketingValue) > rolloutPercentage / 100) return false;
3992
- return true;
4064
+ if (void 0 != rolloutPercentage && await _hash(flag.key, bucketingValue) > rolloutPercentage / 100) return "out_of_rollout_bound";
4065
+ return "match";
3993
4066
  }
3994
4067
  async getMatchingVariant(flag, bucketingValue) {
3995
4068
  const hashValue = await _hash(flag.key, bucketingValue, "variant");
@@ -4507,6 +4580,105 @@ function relativeDateParseForFeatureFlagMatching(value) {
4507
4580
  }
4508
4581
  }
4509
4582
 
4583
+ // ../../node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs
4584
+ function makeUncaughtExceptionHandler(captureFn, onFatalFn) {
4585
+ let calledFatalError = false;
4586
+ return Object.assign((error) => {
4587
+ const userProvidedListenersCount = global.process.listeners("uncaughtException").filter((listener) => "domainUncaughtExceptionClear" !== listener.name && true !== listener._posthogErrorHandler).length;
4588
+ const processWouldExit = 0 === userProvidedListenersCount;
4589
+ captureFn(error, {
4590
+ mechanism: {
4591
+ type: "onuncaughtexception",
4592
+ handled: false
4593
+ }
4594
+ });
4595
+ if (!calledFatalError && processWouldExit) {
4596
+ calledFatalError = true;
4597
+ onFatalFn(error);
4598
+ }
4599
+ }, {
4600
+ _posthogErrorHandler: true
4601
+ });
4602
+ }
4603
+ function addUncaughtExceptionListener(captureFn, onFatalFn) {
4604
+ globalThis.process?.on("uncaughtException", makeUncaughtExceptionHandler(captureFn, onFatalFn));
4605
+ }
4606
+ function addUnhandledRejectionListener(captureFn) {
4607
+ globalThis.process?.on("unhandledRejection", (reason) => captureFn(reason, {
4608
+ mechanism: {
4609
+ type: "onunhandledrejection",
4610
+ handled: false
4611
+ }
4612
+ }));
4613
+ }
4614
+
4615
+ // ../../node_modules/posthog-node/dist/extensions/error-tracking/index.mjs
4616
+ var SHUTDOWN_TIMEOUT = 2e3;
4617
+ var ErrorTracking = class _ErrorTracking {
4618
+ constructor(client2, options, _logger) {
4619
+ this.client = client2;
4620
+ this._exceptionAutocaptureEnabled = options.enableExceptionAutocapture || false;
4621
+ this._logger = _logger;
4622
+ this._rateLimiter = new BucketedRateLimiter({
4623
+ refillRate: 1,
4624
+ bucketSize: 10,
4625
+ refillInterval: 1e4,
4626
+ _logger: this._logger
4627
+ });
4628
+ this.startAutocaptureIfEnabled();
4629
+ }
4630
+ static isPreviouslyCapturedError(x) {
4631
+ return isObject(x) && "__posthog_previously_captured_error" in x && true === x.__posthog_previously_captured_error;
4632
+ }
4633
+ static async buildEventMessage(builder, error, hint, distinctId, additionalProperties) {
4634
+ const properties = {
4635
+ ...additionalProperties
4636
+ };
4637
+ const exceptionProperties = builder.buildFromUnknown(error, hint);
4638
+ exceptionProperties.$exception_list = await builder.modifyFrames(exceptionProperties.$exception_list);
4639
+ return {
4640
+ event: "$exception",
4641
+ distinctId,
4642
+ properties: {
4643
+ ...exceptionProperties,
4644
+ ...properties
4645
+ },
4646
+ _originatedFromCaptureException: true
4647
+ };
4648
+ }
4649
+ startAutocaptureIfEnabled() {
4650
+ if (this.isEnabled()) {
4651
+ addUncaughtExceptionListener(this.onException.bind(this), this.onFatalError.bind(this));
4652
+ addUnhandledRejectionListener(this.onException.bind(this));
4653
+ }
4654
+ }
4655
+ onException(exception, hint) {
4656
+ this.client.addPendingPromise((async () => {
4657
+ if (!_ErrorTracking.isPreviouslyCapturedError(exception)) {
4658
+ const eventMessage = await _ErrorTracking.buildEventMessage(this.client.getErrorPropertiesBuilder(), exception, hint);
4659
+ const exceptionProperties = eventMessage.properties;
4660
+ const exceptionType = exceptionProperties?.$exception_list[0]?.type ?? "Exception";
4661
+ const isRateLimited = this._rateLimiter.consumeRateLimit(exceptionType);
4662
+ if (isRateLimited) return void this._logger.info("Skipping exception capture because of client rate limiting.", {
4663
+ exception: exceptionType
4664
+ });
4665
+ return this.client.capture(eventMessage);
4666
+ }
4667
+ })());
4668
+ }
4669
+ async onFatalError(exception) {
4670
+ console.error(exception);
4671
+ await this.client.shutdown(SHUTDOWN_TIMEOUT);
4672
+ process.exit(1);
4673
+ }
4674
+ isEnabled() {
4675
+ return !this.client.isDisabled && this._exceptionAutocaptureEnabled;
4676
+ }
4677
+ shutdown() {
4678
+ this._rateLimiter.stop();
4679
+ }
4680
+ };
4681
+
4510
4682
  // ../../node_modules/posthog-node/dist/storage-memory.mjs
4511
4683
  var PostHogMemoryStorage = class {
4512
4684
  getProperty(key) {
@@ -4544,6 +4716,12 @@ function normalizeHost(value) {
4544
4716
  const normalizedValue = "string" == typeof value ? value.trim() : "";
4545
4717
  return normalizedValue || DEFAULT_NODE_HOST;
4546
4718
  }
4719
+ function normalizeUnsetPersonProperties(value) {
4720
+ const propertyNames = Array.isArray(value) ? value : [
4721
+ value
4722
+ ];
4723
+ return propertyNames.filter((propertyName) => "string" == typeof propertyName && propertyName.trim().length > 0);
4724
+ }
4547
4725
  function buildFlagEventProperties(flagValues) {
4548
4726
  if (!flagValues) return {};
4549
4727
  const additionalProperties = {};
@@ -4566,7 +4744,7 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4566
4744
  this.options.featureFlagsPollingInterval = "number" == typeof normalizedOptions.featureFlagsPollingInterval ? Math.max(normalizedOptions.featureFlagsPollingInterval, MINIMUM_POLLING_INTERVAL) : THIRTY_SECONDS;
4567
4745
  if ("number" == typeof normalizedOptions.waitUntilDebounceMs) this.options.waitUntilDebounceMs = Math.max(normalizedOptions.waitUntilDebounceMs, 0);
4568
4746
  if ("number" == typeof normalizedOptions.waitUntilMaxWaitMs) this.options.waitUntilMaxWaitMs = Math.max(normalizedOptions.waitUntilMaxWaitMs, 0);
4569
- if (normalizedOptions.personalApiKey) {
4747
+ if (!this.disabled && normalizedOptions.personalApiKey) {
4570
4748
  if (normalizedOptions.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.');
4571
4749
  const shouldEnableLocalEvaluation = false !== normalizedOptions.enableLocalEvaluation;
4572
4750
  if (shouldEnableLocalEvaluation) this.featureFlagsPoller = new FeatureFlagsPoller({
@@ -4667,6 +4845,11 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4667
4845
  getCustomUserAgent() {
4668
4846
  return `${this.getLibraryId()}/${this.getLibraryVersion()}`;
4669
4847
  }
4848
+ getCommonEventProperties() {
4849
+ const commonProperties = super.getCommonEventProperties();
4850
+ if (this.options.isServer ?? true) commonProperties.$is_server = true;
4851
+ return commonProperties;
4852
+ }
4670
4853
  enable() {
4671
4854
  return super.optIn();
4672
4855
  }
@@ -4677,27 +4860,29 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4677
4860
  super.debug(enabled);
4678
4861
  this.featureFlagsPoller?.debug(enabled);
4679
4862
  }
4680
- capture(props) {
4681
- if ("string" == typeof props) this._logger.warn("Called capture() with a string as the first argument when an object was expected.");
4682
- if ("$exception" === props.event && !props._originatedFromCaptureException) this._logger.warn("Using `posthog.capture('$exception')` is unreliable because it does not attach required metadata. Use `posthog.captureException(error)` instead, which attaches required metadata automatically.");
4683
- this.addPendingPromise(this.prepareEventMessage(props).then(({ distinctId, event, properties, options }) => super.captureStateless(distinctId, event, properties, {
4684
- timestamp: options.timestamp,
4685
- disableGeoip: options.disableGeoip,
4686
- uuid: options.uuid
4687
- })).catch((err) => {
4863
+ _warnIfInvalidCapture(props, stringArgumentWarning, exceptionCaptureWarning) {
4864
+ if ("string" == typeof props) this._logger.warn(stringArgumentWarning);
4865
+ if ("$exception" === props.event && !props._originatedFromCaptureException) this._logger.warn(exceptionCaptureWarning);
4866
+ }
4867
+ _capturePreparedEvent(props, immediate) {
4868
+ return this.addPendingPromise(this.prepareEventMessage(props).then(({ distinctId, event, properties, options }) => {
4869
+ const captureOptions = {
4870
+ timestamp: options.timestamp,
4871
+ disableGeoip: options.disableGeoip,
4872
+ uuid: options.uuid
4873
+ };
4874
+ return immediate ? super.captureStatelessImmediate(distinctId, event, properties, captureOptions) : super.captureStateless(distinctId, event, properties, captureOptions);
4875
+ }).catch((err) => {
4688
4876
  if (err) console.error(err);
4689
4877
  }));
4690
4878
  }
4879
+ capture(props) {
4880
+ this._warnIfInvalidCapture(props, "Called capture() with a string as the first argument when an object was expected.", "Using `posthog.capture('$exception')` is unreliable because it does not attach required metadata. Use `posthog.captureException(error)` instead, which attaches required metadata automatically.");
4881
+ this._capturePreparedEvent(props, false);
4882
+ }
4691
4883
  async captureImmediate(props) {
4692
- if ("string" == typeof props) this._logger.warn("Called captureImmediate() with a string as the first argument when an object was expected.");
4693
- if ("$exception" === props.event && !props._originatedFromCaptureException) this._logger.warn("Capturing a `$exception` event via `posthog.captureImmediate('$exception')` is unreliable because it does not attach required metadata. Use `posthog.captureExceptionImmediate(error)` instead, which attaches this metadata by default.");
4694
- return this.addPendingPromise(this.prepareEventMessage(props).then(({ distinctId, event, properties, options }) => super.captureStatelessImmediate(distinctId, event, properties, {
4695
- timestamp: options.timestamp,
4696
- disableGeoip: options.disableGeoip,
4697
- uuid: options.uuid
4698
- })).catch((err) => {
4699
- if (err) console.error(err);
4700
- }));
4884
+ this._warnIfInvalidCapture(props, "Called captureImmediate() with a string as the first argument when an object was expected.", "Capturing a `$exception` event via `posthog.captureImmediate('$exception')` is unreliable because it does not attach required metadata. Use `posthog.captureExceptionImmediate(error)` instead, which attaches this metadata by default.");
4885
+ return this._capturePreparedEvent(props, true);
4701
4886
  }
4702
4887
  identify({ distinctId, properties = {}, disableGeoip }) {
4703
4888
  const { $set, $set_once, $anon_distinct_id, ...rest } = properties;
@@ -4725,6 +4910,28 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4725
4910
  disableGeoip
4726
4911
  });
4727
4912
  }
4913
+ setPersonProperties({ distinctId, properties = {}, propertiesOnce = {} }) {
4914
+ if (0 === Object.keys(properties).length && 0 === Object.keys(propertiesOnce).length) return;
4915
+ const eventProperties = {};
4916
+ if (Object.keys(properties).length > 0) eventProperties.$set = properties;
4917
+ if (Object.keys(propertiesOnce).length > 0) eventProperties.$set_once = propertiesOnce;
4918
+ this.capture({
4919
+ distinctId,
4920
+ event: "$set",
4921
+ properties: eventProperties
4922
+ });
4923
+ }
4924
+ unsetPersonProperties({ distinctId, properties }) {
4925
+ const propertyNames = normalizeUnsetPersonProperties(properties);
4926
+ if (0 === propertyNames.length) return;
4927
+ this.capture({
4928
+ distinctId,
4929
+ event: "$set",
4930
+ properties: {
4931
+ $unset: propertyNames
4932
+ }
4933
+ });
4934
+ }
4728
4935
  alias(data) {
4729
4936
  super.aliasStateless(data.alias, data.distinctId, void 0, {
4730
4937
  disableGeoip: data.disableGeoip
@@ -4764,6 +4971,7 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4764
4971
  };
4765
4972
  }
4766
4973
  async _getFeatureFlagResult(key, distinctId, options = {}, matchValue) {
4974
+ if (this.disabled) return void this._logger.warn("The client is disabled");
4767
4975
  const sendFeatureFlagEvents = options.sendFeatureFlagEvents ?? true;
4768
4976
  if (void 0 !== this._flagOverrides && key in this._flagOverrides) {
4769
4977
  const overrideValue = this._flagOverrides[key];
@@ -4911,6 +5119,7 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4911
5119
  });
4912
5120
  }
4913
5121
  async getRemoteConfigPayload(flagKey) {
5122
+ if (this.disabled) return void this._logger.warn("The client is disabled");
4914
5123
  if (!this.options.personalApiKey) throw new Error("Personal API key is required for remote config payload decryption");
4915
5124
  const response = await this._requestRemoteConfigPayload(flagKey);
4916
5125
  if (!response) return;
@@ -4950,6 +5159,13 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4950
5159
  featureFlagPayloads: {}
4951
5160
  };
4952
5161
  }
5162
+ if (this.disabled) {
5163
+ this._logger.warn("The client is disabled");
5164
+ return {
5165
+ featureFlags: {},
5166
+ featureFlagPayloads: {}
5167
+ };
5168
+ }
4953
5169
  const { groups, disableGeoip, flagKeys } = resolvedOptions || {};
4954
5170
  let { onlyEvaluateLocally, personProperties, groupProperties } = resolvedOptions || {};
4955
5171
  const adjustedProperties = this.addLocalPersonAndGroupProperties(resolvedDistinctId, groups, personProperties, groupProperties);
@@ -5000,6 +5216,14 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
5000
5216
  flags: {}
5001
5217
  });
5002
5218
  }
5219
+ if (this.disabled) {
5220
+ this._logger.warn("The client is disabled");
5221
+ return new FeatureFlagEvaluations({
5222
+ host: this._getFeatureFlagEvaluationsHost(),
5223
+ distinctId: resolvedDistinctId,
5224
+ flags: {}
5225
+ });
5226
+ }
5003
5227
  const { groups, disableGeoip, flagKeys } = resolvedOptions || {};
5004
5228
  let { onlyEvaluateLocally, personProperties, groupProperties } = resolvedOptions || {};
5005
5229
  const adjustedProperties = this.addLocalPersonAndGroupProperties(resolvedDistinctId, groups, personProperties, groupProperties);
@@ -5096,13 +5320,14 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
5096
5320
  }
5097
5321
  _captureFlagCalledEventIfNeeded(params) {
5098
5322
  const { distinctId, key, response, groups, disableGeoip, properties } = params;
5099
- const featureFlagReportedKey = `${key}_${response}`;
5100
- if (distinctId in this.distinctIdHasSentFlagCalls && this.distinctIdHasSentFlagCalls[distinctId].includes(featureFlagReportedKey)) return;
5323
+ const groupSuffix = groups && Object.keys(groups).length > 0 ? `_${JSON.stringify(Object.entries(groups).sort(([a2], [b]) => a2 < b ? -1 : a2 > b ? 1 : 0))}` : "";
5324
+ const featureFlagReportedKey = `${key}_${response}${groupSuffix}`;
5325
+ if (distinctId in this.distinctIdHasSentFlagCalls && this.distinctIdHasSentFlagCalls[distinctId].has(featureFlagReportedKey)) return;
5101
5326
  if (Object.keys(this.distinctIdHasSentFlagCalls).length >= this.maxCacheSize) this.distinctIdHasSentFlagCalls = {};
5102
- if (Array.isArray(this.distinctIdHasSentFlagCalls[distinctId])) this.distinctIdHasSentFlagCalls[distinctId].push(featureFlagReportedKey);
5103
- else this.distinctIdHasSentFlagCalls[distinctId] = [
5327
+ if (this.distinctIdHasSentFlagCalls[distinctId] instanceof Set) this.distinctIdHasSentFlagCalls[distinctId].add(featureFlagReportedKey);
5328
+ else this.distinctIdHasSentFlagCalls[distinctId] = /* @__PURE__ */ new Set([
5104
5329
  featureFlagReportedKey
5105
- ];
5330
+ ]);
5106
5331
  this.capture({
5107
5332
  distinctId,
5108
5333
  event: "$feature_flag_called",
@@ -5192,11 +5417,12 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
5192
5417
  try {
5193
5418
  return await super._shutdown(shutdownTimeoutMs);
5194
5419
  } finally {
5420
+ this.distinctIdHasSentFlagCalls = {};
5195
5421
  resolve3?.();
5196
5422
  }
5197
5423
  }
5198
5424
  async _requestRemoteConfigPayload(flagKey) {
5199
- if (!this.options.personalApiKey) return;
5425
+ if (this.disabled || !this.apiKey || !this.options.personalApiKey) return;
5200
5426
  const url = `${this.host}/api/projects/@current/feature_flags/${flagKey}/remote_config?token=${encodeURIComponent(this.apiKey)}`;
5201
5427
  const options = {
5202
5428
  method: "GET",
@@ -5241,6 +5467,7 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
5241
5467
  };
5242
5468
  }
5243
5469
  async getFeatureFlagsForEvent(distinctId, groups, disableGeoip, sendFeatureFlagsOptions) {
5470
+ if (this.disabled || !this.apiKey) return void this._logger.warn("The client is disabled");
5244
5471
  const finalPersonProperties = sendFeatureFlagsOptions?.personProperties || {};
5245
5472
  const finalGroupProperties = sendFeatureFlagsOptions?.groupProperties || {};
5246
5473
  const flagKeys = sendFeatureFlagsOptions?.flagKeys;
@@ -5299,7 +5526,7 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
5299
5526
  captureException(error, distinctId, additionalProperties, uuid, flags2) {
5300
5527
  if (!ErrorTracking.isPreviouslyCapturedError(error)) {
5301
5528
  const syntheticException = new Error("PostHog syntheticException");
5302
- this.addPendingPromise(ErrorTracking.buildEventMessage(error, {
5529
+ this.addPendingPromise(ErrorTracking.buildEventMessage(this.getErrorPropertiesBuilder(), error, {
5303
5530
  syntheticException
5304
5531
  }, distinctId, additionalProperties).then((msg) => this.capture({
5305
5532
  ...msg,
@@ -5311,7 +5538,7 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
5311
5538
  async captureExceptionImmediate(error, distinctId, additionalProperties, flags2) {
5312
5539
  if (!ErrorTracking.isPreviouslyCapturedError(error)) {
5313
5540
  const syntheticException = new Error("PostHog syntheticException");
5314
- return this.addPendingPromise(ErrorTracking.buildEventMessage(error, {
5541
+ return this.addPendingPromise(ErrorTracking.buildEventMessage(this.getErrorPropertiesBuilder(), error, {
5315
5542
  syntheticException
5316
5543
  }, distinctId, additionalProperties).then((msg) => this.captureImmediate({
5317
5544
  ...msg,
@@ -5358,12 +5585,14 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
5358
5585
  }
5359
5586
  return {};
5360
5587
  }).catch(() => ({})).then((additionalProperties) => {
5361
- const props2 = {
5588
+ const resolvedGroups = eventMessage.groups || groups;
5589
+ return {
5362
5590
  ...additionalProperties,
5363
5591
  ...eventMessage.properties || {},
5364
- $groups: eventMessage.groups || groups
5592
+ ...void 0 !== resolvedGroups && Object.keys(resolvedGroups).length > 0 ? {
5593
+ $groups: resolvedGroups
5594
+ } : {}
5365
5595
  };
5366
- return props2;
5367
5596
  });
5368
5597
  if ("$pageview" === eventMessage.event && this.options.__preview_capture_bot_pageviews && "string" == typeof eventProperties.$raw_user_agent) {
5369
5598
  if (isBlockedUA(eventProperties.$raw_user_agent, this.options.custom_blocked_useragents || [])) {
@@ -5498,17 +5727,6 @@ var PostHogSentryIntegration = class {
5498
5727
  };
5499
5728
 
5500
5729
  // ../../node_modules/posthog-node/dist/entrypoints/index.node.mjs
5501
- ErrorTracking.errorPropertiesBuilder = new error_tracking_exports.ErrorPropertiesBuilder([
5502
- new error_tracking_exports.EventCoercer(),
5503
- new error_tracking_exports.ErrorCoercer(),
5504
- new error_tracking_exports.ObjectCoercer(),
5505
- new error_tracking_exports.StringCoercer(),
5506
- new error_tracking_exports.PrimitiveCoercer()
5507
- ], error_tracking_exports.createStackParser("node:javascript", error_tracking_exports.nodeStackLineParser), [
5508
- createModulerModifier(),
5509
- addSourceContext,
5510
- createRelativePathModifier()
5511
- ]);
5512
5730
  var PostHog = class extends PostHogBackendClient {
5513
5731
  getLibraryId() {
5514
5732
  return "posthog-node";
@@ -5516,6 +5734,19 @@ var PostHog = class extends PostHogBackendClient {
5516
5734
  initializeContext() {
5517
5735
  return new PostHogContext();
5518
5736
  }
5737
+ createErrorPropertiesBuilder() {
5738
+ return new error_tracking_exports.ErrorPropertiesBuilder([
5739
+ new error_tracking_exports.EventCoercer(),
5740
+ new error_tracking_exports.ErrorCoercer(),
5741
+ new error_tracking_exports.ObjectCoercer(),
5742
+ new error_tracking_exports.StringCoercer(),
5743
+ new error_tracking_exports.PrimitiveCoercer()
5744
+ ], error_tracking_exports.createStackParser("node:javascript", error_tracking_exports.nodeStackLineParser), [
5745
+ createModulerModifier(),
5746
+ addSourceContext,
5747
+ createRelativePathModifier()
5748
+ ]);
5749
+ }
5519
5750
  };
5520
5751
 
5521
5752
  // ../telemetry/src/posthog.ts
@@ -5606,6 +5837,8 @@ var FAILURE_CODES = {
5606
5837
  UNINSTALL_TOOLSERVER_STOP_FAILED: "UNINSTALL_TOOLSERVER_STOP_FAILED",
5607
5838
  UNINSTALL_PACKAGE_ACTION_FAILED: "UNINSTALL_PACKAGE_ACTION_FAILED",
5608
5839
  UNINSTALL_UNCLASSIFIED_FAILED: "UNINSTALL_UNCLASSIFIED_FAILED",
5840
+ VEGA_CLI_COMMAND_FAILED: "VEGA_CLI_COMMAND_FAILED",
5841
+ VEGA_INPUT_UNAVAILABLE: "VEGA_INPUT_UNAVAILABLE",
5609
5842
  ANDROID_ADB_NOT_FOUND: "ANDROID_ADB_NOT_FOUND",
5610
5843
  ANDROID_EMULATOR_NOT_FOUND: "ANDROID_EMULATOR_NOT_FOUND",
5611
5844
  ANDROID_ADB_COMMAND_FAILED: "ANDROID_ADB_COMMAND_FAILED",
@@ -5754,6 +5987,7 @@ var FAILURE_KINDS = [
5754
5987
  var FAILURE_COMMANDS = [
5755
5988
  "adb",
5756
5989
  "emulator",
5990
+ "vega",
5757
5991
  "xcrun_simctl",
5758
5992
  "xctrace",
5759
5993
  "native_devtools",
@@ -5794,7 +6028,7 @@ var FAILURE_SPAWN_CODE_SET = new Set(FAILURE_SPAWN_CODES);
5794
6028
  import { randomUUID as randomUUID2 } from "node:crypto";
5795
6029
 
5796
6030
  // ../telemetry/src/events.ts
5797
- var PLATFORMS = ["ios", "android", "chromium"];
6031
+ var PLATFORMS = ["ios", "ios-remote", "android", "chromium", "vega"];
5798
6032
 
5799
6033
  // ../telemetry/src/ai-identity.ts
5800
6034
  var AI_CLIENTS = [
@@ -5972,8 +6206,7 @@ var ALLOWED = {
5972
6206
  uptime_ms: DURATION_MS,
5973
6207
  total_tool_calls: COUNT,
5974
6208
  ...FAILURE_SIGNAL
5975
- },
5976
- "telemetry:opt_out": {}
6209
+ }
5977
6210
  };
5978
6211
  function sanitize(event, raw) {
5979
6212
  const validators = ALLOWED[event];
@@ -5991,6 +6224,56 @@ function sanitize(event, raw) {
5991
6224
  // ../telemetry/src/base-props.ts
5992
6225
  import { randomUUID as randomUUID3 } from "node:crypto";
5993
6226
 
6227
+ // ../telemetry/src/cloud-agent-detect.ts
6228
+ import { existsSync as existsSync2 } from "node:fs";
6229
+ var CLAUDE_CLOUD_ENV_KINDS = /* @__PURE__ */ new Set(["byoc", "anthropic_cloud"]);
6230
+ var CLAUDE_REMOTE_ENTRYPOINTS = /* @__PURE__ */ new Set([
6231
+ "remote",
6232
+ "remote_baku",
6233
+ "remote_cowork",
6234
+ "remote_desktop",
6235
+ "remote_mobile",
6236
+ "claude-in-teams"
6237
+ ]);
6238
+ function isClaudeCodeCloud(env) {
6239
+ const kind = env.CLAUDE_CODE_ENVIRONMENT_KIND;
6240
+ if (kind && CLAUDE_CLOUD_ENV_KINDS.has(kind)) return true;
6241
+ const entrypoint = env.CLAUDE_CODE_ENTRYPOINT;
6242
+ if (entrypoint && CLAUDE_REMOTE_ENTRYPOINTS.has(entrypoint)) return true;
6243
+ return Boolean(env.CLAUDE_CODE_REMOTE_SESSION_ID);
6244
+ }
6245
+ function isCursorCloud(env) {
6246
+ return Boolean(env.CURSOR_AGENT_WORKER_ID) || Boolean(env.CURSOR_WORKER_POOL_NAME);
6247
+ }
6248
+ function isCopilotAgent(env) {
6249
+ if (!env.GITHUB_ACTIONS) return false;
6250
+ const actor = (env.GITHUB_ACTOR ?? "").toLowerCase();
6251
+ const workflowRef = (env.GITHUB_WORKFLOW_REF ?? "").toLowerCase();
6252
+ return actor === "copilot" || actor.includes("copilot-swe-agent") || workflowRef.includes("copilot-swe-agent");
6253
+ }
6254
+ function isReplitAgent(env) {
6255
+ return Boolean(env.REPLIT_AGENT);
6256
+ }
6257
+ var DEVIN_MARKER_PATH = "/opt/.devin";
6258
+ var JULES_MARKER_PATH = "/opt/environment_summary.sh";
6259
+ function safeExists(fileExists, path10) {
6260
+ try {
6261
+ return fileExists(path10);
6262
+ } catch {
6263
+ return false;
6264
+ }
6265
+ }
6266
+ function detectCloudAgent(env = process.env, opts = {}) {
6267
+ if (isClaudeCodeCloud(env)) return "claude_code";
6268
+ if (isCursorCloud(env)) return "cursor";
6269
+ if (isCopilotAgent(env)) return "copilot";
6270
+ if (isReplitAgent(env)) return "replit";
6271
+ const fileExists = opts.fileExists ?? existsSync2;
6272
+ if (safeExists(fileExists, DEVIN_MARKER_PATH)) return "devin";
6273
+ if (safeExists(fileExists, JULES_MARKER_PATH)) return "jules";
6274
+ return null;
6275
+ }
6276
+
5994
6277
  // ../../node_modules/ci-info/vendors.json
5995
6278
  var vendors_default = [
5996
6279
  {
@@ -6396,7 +6679,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
6396
6679
  var SESSION_ID2 = randomUUID3();
6397
6680
  function readCliVersion() {
6398
6681
  if (true) {
6399
- return "0.12.1";
6682
+ return "0.13.0";
6400
6683
  }
6401
6684
  return "0.0.0";
6402
6685
  }
@@ -6414,6 +6697,7 @@ function getInvariantProps() {
6414
6697
  arch: process.arch,
6415
6698
  is_tty: Boolean(process.stdout.isTTY),
6416
6699
  is_ci: isCi(),
6700
+ cloud_agent: detectCloudAgent(),
6417
6701
  $process_person_profile: false
6418
6702
  };
6419
6703
  }
@@ -6543,7 +6827,7 @@ function readConfigObject() {
6543
6827
  }
6544
6828
  return {};
6545
6829
  }
6546
- var LOCK_STALE_MS = 1e4;
6830
+ var LOCK_STALE_MS2 = 1e4;
6547
6831
  var LOCK_MAX_WAIT_MS = 2e3;
6548
6832
  var LOCK_RETRY_MS = 25;
6549
6833
  function sleepSync(ms) {
@@ -6564,7 +6848,7 @@ function acquireConfigLock() {
6564
6848
  } catch (err) {
6565
6849
  if (err.code !== "EEXIST") return null;
6566
6850
  try {
6567
- if (Date.now() - fs3.statSync(lockPath).mtimeMs > LOCK_STALE_MS) {
6851
+ if (Date.now() - fs3.statSync(lockPath).mtimeMs > LOCK_STALE_MS2) {
6568
6852
  fs3.unlinkSync(lockPath);
6569
6853
  continue;
6570
6854
  }
@@ -6828,39 +7112,12 @@ async function shutdown(timeoutMs = SHORT_FLUSH_TIMEOUT_MS) {
6828
7112
  state = null;
6829
7113
  }
6830
7114
  }
6831
- function isEnabled2() {
6832
- return isEnabled();
6833
- }
6834
7115
  function markEnabled() {
6835
7116
  writeConsentFlag(true);
6836
7117
  }
6837
7118
  async function markDisabled() {
6838
7119
  try {
6839
- const wasEnabled = isEnabled();
6840
- let client2 = getConstructedClient();
6841
- if (wasEnabled && peekAnonId() !== null) {
6842
- const built = buildPayload("telemetry:opt_out", {});
6843
- if (built && isDebugEnabled()) {
6844
- emitDebugPayload({
6845
- event: "telemetry:opt_out",
6846
- distinctId: built.distinctId,
6847
- properties: built.properties,
6848
- ts: (/* @__PURE__ */ new Date()).toISOString()
6849
- });
6850
- }
6851
- client2 = getClient();
6852
- if (built && client2) {
6853
- try {
6854
- client2.capture({
6855
- distinctId: built.distinctId,
6856
- event: "telemetry:opt_out",
6857
- properties: built.properties
6858
- });
6859
- } catch (err) {
6860
- emitDebugError("markDisabled: capture(telemetry:opt_out) failed", err);
6861
- }
6862
- }
6863
- }
7120
+ const client2 = getConstructedClient();
6864
7121
  writeConsentFlag(false);
6865
7122
  if (client2) {
6866
7123
  try {
@@ -7663,6 +7920,9 @@ async function runDetached(paths, port, host, idleTimeoutMinutes, token) {
7663
7920
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
7664
7921
  bundlePath: paths.bundlePath,
7665
7922
  host,
7923
+ // Mark this as an explicitly-started (possibly supervisor-managed) server so
7924
+ // the MCP auto-spawn path's kill-before-respawn never terminates it.
7925
+ managed: "cli",
7666
7926
  ...token ? { token } : {}
7667
7927
  });
7668
7928
  const url = formatUrl(host, actualPort);
@@ -7703,6 +7963,8 @@ async function runForeground(paths, port, host, idleTimeoutMinutes, token) {
7703
7963
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
7704
7964
  bundlePath: paths.bundlePath,
7705
7965
  host,
7966
+ // See runDetached: tag CLI-started servers so auto-spawn won't kill them.
7967
+ managed: "cli",
7706
7968
  ...token ? { token } : {}
7707
7969
  });
7708
7970
  stateWritten = true;
@@ -8790,7 +9052,7 @@ var n = class extends V {
8790
9052
  import { styleText as styleText2, stripVTControlCharacters } from "node:util";
8791
9053
  import process$1 from "node:process";
8792
9054
  var import_sisteransi2 = __toESM(require_src(), 1);
8793
- import { existsSync as existsSync3, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
9055
+ import { existsSync as existsSync5, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
8794
9056
  import { dirname as dirname5, join as join9 } from "node:path";
8795
9057
  function isUnicodeSupported() {
8796
9058
  if (process$1.platform !== "win32") {
@@ -8800,7 +9062,7 @@ function isUnicodeSupported() {
8800
9062
  }
8801
9063
  var unicode = isUnicodeSupported();
8802
9064
  var isCI = () => process.env.CI === "true";
8803
- var unicodeOr = (e, o2) => unicode ? e : o2;
9065
+ var unicodeOr = (o2, e) => unicode ? o2 : e;
8804
9066
  var S_STEP_ACTIVE = unicodeOr("\u25C6", "*");
8805
9067
  var S_STEP_CANCEL = unicodeOr("\u25A0", "x");
8806
9068
  var S_STEP_ERROR = unicodeOr("\u25B2", "x");
@@ -8826,8 +9088,8 @@ var S_INFO = unicodeOr("\u25CF", "\u2022");
8826
9088
  var S_SUCCESS = unicodeOr("\u25C6", "*");
8827
9089
  var S_WARN = unicodeOr("\u25B2", "!");
8828
9090
  var S_ERROR = unicodeOr("\u25A0", "x");
8829
- var symbol = (e) => {
8830
- switch (e) {
9091
+ var symbol = (o2) => {
9092
+ switch (o2) {
8831
9093
  case "initial":
8832
9094
  case "active":
8833
9095
  return styleText2("cyan", S_STEP_ACTIVE);
@@ -8839,8 +9101,8 @@ var symbol = (e) => {
8839
9101
  return styleText2("green", S_STEP_SUBMIT);
8840
9102
  }
8841
9103
  };
8842
- var symbolBar = (e) => {
8843
- switch (e) {
9104
+ var symbolBar = (o2) => {
9105
+ switch (o2) {
8844
9106
  case "initial":
8845
9107
  case "active":
8846
9108
  return styleText2("cyan", S_BAR);
@@ -8852,6 +9114,10 @@ var symbolBar = (e) => {
8852
9114
  return styleText2("green", S_BAR);
8853
9115
  }
8854
9116
  };
9117
+ function formatInstructionFooter(o2, e) {
9118
+ const r2 = [`${e ? `${styleText2("cyan", S_BAR)} ` : ""}${o2.join(" \u2022 ")}`];
9119
+ return e && r2.push(styleText2("cyan", S_BAR_END)), r2;
9120
+ }
8855
9121
  var E$1 = (l2, o2, g, c2, h2, O = false) => {
8856
9122
  let r2 = o2, w = 0;
8857
9123
  if (O)
@@ -8954,6 +9220,11 @@ ${g}
8954
9220
  }
8955
9221
  }).prompt();
8956
9222
  };
9223
+ var MULTISELECT_INSTRUCTIONS = [
9224
+ `${styleText2("dim", "\u2191/\u2193")} to navigate`,
9225
+ `${styleText2("dim", "Space:")} select`,
9226
+ `${styleText2("dim", "Enter:")} confirm`
9227
+ ];
8957
9228
  var log = {
8958
9229
  message: (s = [], {
8959
9230
  symbol: e = styleText2("gray", S_BAR),
@@ -9100,20 +9371,24 @@ var u2 = {
9100
9371
  heavy: unicodeOr("\u2501", "="),
9101
9372
  block: unicodeOr("\u2588", "#")
9102
9373
  };
9103
- var c = (e, a2) => e.includes(`
9104
- `) ? e.split(`
9105
- `).map((t2) => a2(t2)).join(`
9106
- `) : a2(e);
9107
- var select = (e) => {
9108
- const a2 = (t2, d) => {
9109
- const s = t2.label ?? String(t2.value);
9110
- switch (d) {
9374
+ var SELECT_INSTRUCTIONS = [
9375
+ `${styleText2("dim", "\u2191/\u2193")} to navigate`,
9376
+ `${styleText2("dim", "Enter:")} confirm`
9377
+ ];
9378
+ var c = (t2, a2) => t2.includes(`
9379
+ `) ? t2.split(`
9380
+ `).map((i2) => a2(i2)).join(`
9381
+ `) : a2(t2);
9382
+ var select = (t2) => {
9383
+ const a2 = (i2, m) => {
9384
+ const s = i2.label ?? String(i2.value);
9385
+ switch (m) {
9111
9386
  case "disabled":
9112
- return `${styleText2("gray", S_RADIO_INACTIVE)} ${c(s, (n2) => styleText2("gray", n2))}${t2.hint ? ` ${styleText2("dim", `(${t2.hint ?? "disabled"})`)}` : ""}`;
9387
+ return `${styleText2("gray", S_RADIO_INACTIVE)} ${c(s, (n2) => styleText2("gray", n2))}${i2.hint ? ` ${styleText2("dim", `(${i2.hint ?? "disabled"})`)}` : ""}`;
9113
9388
  case "selected":
9114
9389
  return `${c(s, (n2) => styleText2("dim", n2))}`;
9115
9390
  case "active":
9116
- return `${styleText2("green", S_RADIO_ACTIVE)} ${s}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}`;
9391
+ return `${styleText2("green", S_RADIO_ACTIVE)} ${s}${i2.hint ? ` ${styleText2("dim", `(${i2.hint})`)}` : ""}`;
9117
9392
  case "cancelled":
9118
9393
  return `${c(s, (n2) => styleText2(["strikethrough", "dim"], n2))}`;
9119
9394
  default:
@@ -9121,52 +9396,53 @@ var select = (e) => {
9121
9396
  }
9122
9397
  };
9123
9398
  return new a({
9124
- options: e.options,
9125
- signal: e.signal,
9126
- input: e.input,
9127
- output: e.output,
9128
- initialValue: e.initialValue,
9399
+ options: t2.options,
9400
+ signal: t2.signal,
9401
+ input: t2.input,
9402
+ output: t2.output,
9403
+ initialValue: t2.initialValue,
9129
9404
  render() {
9130
- const t2 = e.withGuide ?? settings.withGuide, d = `${symbol(this.state)} `, s = `${symbolBar(this.state)} `, n2 = wrapTextWithPrefix(
9131
- e.output,
9132
- e.message,
9405
+ const i2 = t2.withGuide ?? settings.withGuide, m = `${symbol(this.state)} `, s = `${symbolBar(this.state)} `, n2 = wrapTextWithPrefix(
9406
+ t2.output,
9407
+ t2.message,
9133
9408
  s,
9134
- d
9135
- ), u3 = `${t2 ? `${styleText2("gray", S_BAR)}
9409
+ m
9410
+ ), u3 = `${i2 ? `${styleText2("gray", S_BAR)}
9136
9411
  ` : ""}${n2}
9137
9412
  `;
9138
9413
  switch (this.state) {
9139
9414
  case "submit": {
9140
- const r2 = t2 ? `${styleText2("gray", S_BAR)} ` : "", l2 = wrapTextWithPrefix(
9141
- e.output,
9415
+ const r2 = i2 ? `${styleText2("gray", S_BAR)} ` : "", o2 = wrapTextWithPrefix(
9416
+ t2.output,
9142
9417
  a2(this.options[this.cursor], "selected"),
9143
9418
  r2
9144
9419
  );
9145
- return `${u3}${l2}`;
9420
+ return `${u3}${o2}`;
9146
9421
  }
9147
9422
  case "cancel": {
9148
- const r2 = t2 ? `${styleText2("gray", S_BAR)} ` : "", l2 = wrapTextWithPrefix(
9149
- e.output,
9423
+ const r2 = i2 ? `${styleText2("gray", S_BAR)} ` : "", o2 = wrapTextWithPrefix(
9424
+ t2.output,
9150
9425
  a2(this.options[this.cursor], "cancelled"),
9151
9426
  r2
9152
9427
  );
9153
- return `${u3}${l2}${t2 ? `
9428
+ return `${u3}${o2}${i2 ? `
9154
9429
  ${styleText2("gray", S_BAR)}` : ""}`;
9155
9430
  }
9156
9431
  default: {
9157
- const r2 = t2 ? `${styleText2("cyan", S_BAR)} ` : "", l2 = t2 ? styleText2("cyan", S_BAR_END) : "", g = u3.split(`
9158
- `).length, h2 = t2 ? 2 : 1;
9432
+ const r2 = i2 ? `${styleText2("cyan", S_BAR)} ` : "", o2 = u3.split(`
9433
+ `).length, $ = formatInstructionFooter(SELECT_INSTRUCTIONS, i2), h2 = $.join(`
9434
+ `), b = $.length + 1;
9159
9435
  return `${u3}${r2}${limitOptions({
9160
- output: e.output,
9436
+ output: t2.output,
9161
9437
  cursor: this.cursor,
9162
9438
  options: this.options,
9163
- maxItems: e.maxItems,
9439
+ maxItems: t2.maxItems,
9164
9440
  columnPadding: r2.length,
9165
- rowPadding: g + h2,
9166
- style: (p, b) => a2(p, p.disabled ? "disabled" : b ? "active" : "inactive")
9441
+ rowPadding: o2 + b,
9442
+ style: (p, x) => a2(p, p.disabled ? "disabled" : x ? "active" : "inactive")
9167
9443
  }).join(`
9168
9444
  ${r2}`)}
9169
- ${l2}
9445
+ ${h2}
9170
9446
  `;
9171
9447
  }
9172
9448
  }
@@ -9457,6 +9733,8 @@ async function preflightHealth(url, token) {
9457
9733
  signal: controller.signal,
9458
9734
  headers: token ? { Authorization: `Bearer ${token}` } : {}
9459
9735
  });
9736
+ await res.body?.cancel().catch(() => {
9737
+ });
9460
9738
  if (!res.ok) {
9461
9739
  const hint = res.status === 401 ? " \u2014 the server requires a token; pass --token or use the argent:// link from `server start`" : res.status === 403 ? " \u2014 the server refused this host (DNS-rebinding guard); reach it by its bind host or start it with --host" : "";
9462
9740
  return { ok: false, error: `${res.status} ${res.statusText}${hint}` };
@@ -9719,7 +9997,7 @@ function printStatus() {
9719
9997
  console.log(` anon id: ${anonLabel}`);
9720
9998
  }
9721
9999
  async function cmdEnable() {
9722
- const wasEnabled = isEnabled2();
10000
+ const wasEnabled = isEnabled();
9723
10001
  markEnabled();
9724
10002
  if (wasEnabled) {
9725
10003
  console.log(import_picocolors3.default.dim("Telemetry was already enabled."));
@@ -9729,7 +10007,7 @@ async function cmdEnable() {
9729
10007
  await shutdown();
9730
10008
  }
9731
10009
  async function cmdDisable() {
9732
- const wasEnabled = isEnabled2();
10010
+ const wasEnabled = isEnabled();
9733
10011
  if (!wasEnabled) {
9734
10012
  console.log(import_picocolors3.default.dim("Telemetry was already disabled."));
9735
10013
  await shutdown();