@swmansion/argent 0.13.0 → 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];
2084
- return {
2085
- response: flagDetail,
2086
- requestId: flagsResponse.requestId,
2087
- evaluatedAt: flagsResponse.evaluatedAt
2088
- };
2089
- }
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;
2099
- }
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;
2104
- }
2105
- async getFeatureFlagsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
2106
- await this._initPromise;
2107
- return await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate);
2108
- }
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
2116
- };
2117
- return {
2118
- flags: featureFlagDetails.featureFlags,
2119
- payloads: featureFlagDetails.featureFlagPayloads,
2120
- requestId: featureFlagDetails.requestId
2121
- };
2122
- }
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
- };
2141
- }
2142
- return flagsResponse;
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);
2143
2119
  }
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 [];
2150
- }
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;
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];
2166
2129
  }
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
- }
2176
- get props() {
2177
- if (!this._props) this._props = this.getPersistedProperty(types_PostHogPersistedProperty.Props);
2178
- return this._props || {};
2179
- }
2180
- set props(val) {
2181
- this._props = val;
2182
- }
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
- });
2191
- }
2192
- async unregister(property) {
2193
- this.wrap(() => {
2194
- delete this.props[property];
2195
- this.setPersistedProperty(types_PostHogPersistedProperty.Props, this.props);
2196
- });
2197
- }
2198
- processBeforeEnqueue(message) {
2199
- return message;
2200
- }
2201
- async flushStorage() {
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);
2202
2133
  }
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.");
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] = "";
2213
2150
  }
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
- });
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);
2222
2156
  }
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()
2236
- };
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"
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);
2248
2200
  }
2249
- },
2250
- body: gzippedPayload || payload
2251
- };
2252
- 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);
2201
+ }
2202
+ typeName = void 0;
2258
2203
  }
2259
- }
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()
2268
- };
2269
- const addGeoipDisableProperty = options?.disableGeoip ?? this.disableGeoip;
2270
- if (addGeoipDisableProperty) {
2271
- if (!message.properties) message.properties = {};
2272
- message["properties"]["$geoip_disable"] = true;
2204
+ if (method) {
2205
+ typeName = object;
2206
+ methodName = method;
2273
2207
  }
2274
- if (message.distinctId) {
2275
- message.distinct_id = message.distinctId;
2276
- delete message.distinctId;
2208
+ if ("<anonymous>" === method) {
2209
+ methodName = void 0;
2210
+ functionName = void 0;
2277
2211
  }
2278
- return message;
2279
- }
2280
- clearFlushTimer() {
2281
- if (this._flushTimer) {
2282
- clearTimeout(this._flushTimer);
2283
- this._flushTimer = void 0;
2212
+ if (void 0 === functionName) {
2213
+ methodName = methodName || UNKNOWN_FUNCTION;
2214
+ functionName = typeName ? `${typeName}.${methodName}` : methodName;
2284
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];
2220
+ return {
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
2228
+ };
2285
2229
  }
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;
2304
- }
2305
- getCustomHeaders() {
2306
- const customUserAgent = this.getCustomUserAgent();
2307
- const headers = {};
2308
- if (customUserAgent && "" !== customUserAgent) headers["User-Agent"] = customUserAgent;
2309
- return headers;
2310
- }
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"
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;
2344
2276
  }
2345
- },
2346
- body: gzippedPayload || payload
2347
- };
2348
- const retryOptions = {
2349
- retryCheck: (err) => {
2350
- if (isPostHogFetchContentTooLargeError(err)) return false;
2351
- return isPostHogFetchError(err);
2352
2277
  }
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;
2278
+ if (frames.length >= STACKTRACE_FRAME_LIMIT) break;
2367
2279
  }
2368
- await persistQueueChange();
2369
- sentMessages.push(...batchMessages);
2370
2280
  }
2371
- this._events.emit("flush", sentMessages);
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);
2289
+ }
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
+ };
2299
+ }
2300
+ getType(candidate) {
2301
+ return this.isDOMError(candidate) ? "DOMError" : "DOMException";
2302
+ }
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;
2372
2307
  }
2373
- async _sendLogsBatch(payload) {
2374
- if (this.disabled) return {
2375
- kind: "fatal",
2376
- error: new Error("The client is disabled")
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
2377
2328
  };
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
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
2391
2357
  };
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
- };
2414
- }
2358
+ return exceptionLike;
2415
2359
  }
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
- }
2427
- }
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
2449
- });
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;
2450
2367
  }
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
- }
2368
+ coerce(input, ctx) {
2369
+ const [type, value] = this.getInfos(input);
2370
+ return {
2371
+ type: type ?? "Error",
2372
+ value: value ?? input,
2373
+ stack: ctx.syntheticException?.stack,
2374
+ synthetic: true
2469
2375
  };
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);
2484
- }
2485
2376
  }
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;
2490
- });
2491
- return this.shutdownPromise;
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];
2384
+ }
2385
+ return [
2386
+ type,
2387
+ value
2388
+ ];
2492
2389
  }
2493
2390
  };
2494
2391
 
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
- });
2524
-
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
- }
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)}...`;
2554
2412
  }
2555
- return acc;
2556
- }, {});
2557
- return cachedFilenameChunkIds;
2413
+ }
2414
+ return "";
2558
2415
  }
2559
2416
 
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;
2567
- }
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"
2582
- };
2583
- }
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;
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;
2587
2421
  }
2588
- coerceFallback(ctx) {
2422
+ coerce(candidate, ctx) {
2423
+ const errorProperty = this.getErrorPropertyFromObject(candidate);
2424
+ if (errorProperty) return ctx.apply(errorProperty);
2589
2425
  return {
2590
- type: "Error",
2591
- value: "Unknown error",
2426
+ type: this.getType(candidate),
2427
+ value: this.getValue(candidate),
2592
2428
  stack: ctx.syntheticException?.stack,
2429
+ level: this.isSeverityLevel(candidate.level) ? candidate.level : "error",
2593
2430
  synthetic: true
2594
2431
  };
2595
2432
  }
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);
2601
- return {
2602
- ...err,
2603
- cause,
2604
- stack
2605
- };
2433
+ getType(err) {
2434
+ return isEvent(err) ? err.constructor.name : "Error";
2606
2435
  }
2607
- applyChunkIds(frames, chunkIdMap) {
2608
- return frames.map((frame) => {
2609
- if (frame.filename && chunkIdMap) frame.chunk_id = chunkIdMap[frame.filename];
2610
- return frame;
2611
- });
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}`;
2612
2446
  }
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);
2447
+ isSeverityLevel(x) {
2448
+ return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;
2616
2449
  }
2617
- async applyModifiers(frames) {
2618
- let newFrames = frames;
2619
- for (const modifier of this.modifiers) newFrames = await modifier(newFrames);
2620
- return newFrames;
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
+ }
2621
2455
  }
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;
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
+ }
2644
2463
  }
2645
- buildParsingContext(hint) {
2646
- const context = {
2647
- chunkIdMap: getFilenameToChunkIdMap(this.stackParser),
2648
- skipFirstLines: hint.skipFirstLines ?? 1
2649
- };
2650
- return context;
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);
2651
2470
  }
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);
2658
- }
2659
- };
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)
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
2666
2478
  };
2667
- return context;
2668
2479
  }
2669
2480
  };
2670
2481
 
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
- ];
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
2493
+ };
2494
+ }
2696
2495
  };
2697
2496
 
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);
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);
2707
2501
  }
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
- }
2502
+ isCustomEventWrappingRejection(err) {
2503
+ if (!isEvent(err)) return false;
2504
+ try {
2505
+ const detail = err.detail;
2506
+ return null != detail && "object" == typeof detail && "reason" in detail;
2507
+ } catch {
2508
+ return false;
2718
2509
  }
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);
2721
2510
  }
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] = "";
2738
- }
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
2518
+ };
2519
+ return ctx.apply(reason);
2520
+ }
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 {
2739
2526
  }
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);
2527
+ return error;
2744
2528
  }
2745
2529
  };
2746
2530
 
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;
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();
2536
+ }
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;
2543
+ }
2544
+ set(key, value) {
2545
+ this._cache.set(key, value);
2546
+ }
2547
+ reduce() {
2548
+ while (this._cache.size >= this._maxSize) {
2549
+ const value = this._cache.keys().next().value;
2550
+ if (value) this._cache.delete(value);
2551
+ }
2552
+ }
2752
2553
  };
2753
2554
 
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;
2555
+ // ../../node_modules/@posthog/core/dist/error-tracking/exception-steps.mjs
2556
+ var EXCEPTION_STEP_INTERNAL_FIELDS = {
2557
+ MESSAGE: "$message",
2558
+ TIMESTAMP: "$timestamp"
2759
2559
  };
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;
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
2764
2567
  };
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);
2788
- }
2789
- }
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;
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;
2799
2587
  }
2800
- if (void 0 === functionName) {
2801
- methodName = methodName || UNKNOWN_FUNCTION;
2802
- functionName = typeName ? `${typeName}.${methodName}` : methodName;
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
2614
+ });
2615
+ this._totalBytes += bytes;
2616
+ this._trimToMaxBytes();
2617
+ }
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;
2803
2632
  }
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];
2633
+ }
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;
2808
2652
  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
2653
+ step: parsedStep,
2654
+ json
2816
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;
2677
+ });
2678
+ } catch {
2679
+ return;
2680
+ }
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
+ }
2692
+
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();
2817
2706
  }
2818
- if (line.match(FILENAME_MATCH)) return {
2819
- filename: line,
2820
- platform
2821
- };
2822
2707
  };
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/");
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 {
2721
+ }
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();
2826
2725
  }
2827
- function _parseIntOrUndefined(input) {
2828
- return parseInt(input || "", 10) || void 0;
2726
+ function isPostHogFetchError(err) {
2727
+ return "object" == typeof err && (err instanceof PostHogFetchHttpError || isPostHogFetchNetworkError(err));
2829
2728
  }
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
- }));
2729
+ function isPostHogFetchNetworkError(err) {
2730
+ return err instanceof PostHogFetchNetworkError;
2843
2731
  }
2844
- function getLastStackFrame(arr) {
2845
- return arr[arr.length - 1] || {};
2732
+ function isPostHogFetchContentTooLargeError(err) {
2733
+ return "object" == typeof err && err instanceof PostHogFetchHttpError && 413 === err.status;
2846
2734
  }
2847
- function createDefaultStackParser() {
2848
- return createStackParser("web:javascript", chromeStackLineParser, geckoStackLineParser);
2735
+ function isPostHogEventProperties(value) {
2736
+ return null !== value && "object" == typeof value && !Array.isArray(value);
2849
2737
  }
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
- }
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());
2750
+ }
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
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);
2787
+ }
2788
+ logMsgIfDebug(fn) {
2789
+ if (this.isDebug) fn();
2790
+ }
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());
2795
+ }
2796
+ getCommonEventProperties() {
2797
+ return {
2798
+ $lib: this.getLibraryId(),
2799
+ $lib_version: this.getLibraryVersion()
2800
+ };
2801
+ }
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);
2808
+ });
2809
+ }
2810
+ async optOut() {
2811
+ this.wrap(() => {
2812
+ this.setPersistedProperty(types_PostHogPersistedProperty.OptedOut, true);
2813
+ });
2814
+ }
2815
+ on(event, cb) {
2816
+ return this._events.on(event, cb);
2817
+ }
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
+ };
2868
2826
  }
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);
2877
2827
  }
2878
- coerce(err, ctx) {
2879
- const hasStack = isString(err.stack);
2828
+ get isDebug() {
2829
+ return !!this.removeDebugCallback;
2830
+ }
2831
+ get isDisabled() {
2832
+ return this.disabled;
2833
+ }
2834
+ buildPayload(payload) {
2880
2835
  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
2836
+ distinct_id: payload.distinct_id,
2837
+ event: payload.event,
2838
+ properties: {
2839
+ ...payload.properties || {},
2840
+ ...this.getCommonEventProperties()
2841
+ }
2886
2842
  };
2887
2843
  }
2888
- getType(candidate) {
2889
- return this.isDOMError(candidate) ? "DOMError" : "DOMException";
2844
+ addPendingPromise(promise) {
2845
+ return this.promiseQueue.add(promise);
2890
2846
  }
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;
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
+ });
2895
2858
  }
2896
- isDOMException(err) {
2897
- return isBuiltin(err, "DOMException");
2859
+ async identifyStatelessImmediate(distinctId, properties, options) {
2860
+ const payload = {
2861
+ ...this.buildPayload({
2862
+ distinct_id: distinctId,
2863
+ event: "$identify",
2864
+ properties
2865
+ })
2866
+ };
2867
+ await this.sendImmediate("identify", payload, options);
2898
2868
  }
2899
- isDOMError(err) {
2900
- return isBuiltin(err, "DOMError");
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
+ });
2878
+ }
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);
2886
+ }
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
2909
+ }
2910
+ });
2911
+ await this.sendImmediate("alias", payload, options);
2912
+ }
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 || {}
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"
2939
+ }
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
+ });
2901
2947
  }
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);
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
+ });
2908
2983
  }
2909
- coerce(err, ctx) {
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
+ };
2997
+ }
2910
2998
  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
2999
+ type: "unknown_error"
2916
3000
  };
2917
3001
  }
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;
2928
- }
2929
- };
2930
-
2931
- // ../../node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
2932
- var ErrorEventCoercer = class {
2933
- constructor() {
2934
- }
2935
- match(err) {
2936
- return isErrorEvent(err) && void 0 != err.error;
2937
- }
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
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;
3011
+ return {
3012
+ response,
3013
+ requestId: flagDetailResponse.requestId
2945
3014
  };
2946
- return exceptionLike;
2947
- }
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;
2955
3015
  }
2956
- coerce(input, ctx) {
2957
- const [type, value] = this.getInfos(input);
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];
2958
3024
  return {
2959
- type: type ?? "Error",
2960
- value: value ?? input,
2961
- stack: ctx.syntheticException?.stack,
2962
- synthetic: true
3025
+ response: flagDetail,
3026
+ requestId: flagsResponse.requestId,
3027
+ evaluatedAt: flagsResponse.evaluatedAt
2963
3028
  };
2964
3029
  }
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
- ];
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;
2977
3039
  }
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
- }
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;
3001
3044
  }
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;
3045
+ async getFeatureFlagsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
3046
+ await this._initPromise;
3047
+ return await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate);
3009
3048
  }
3010
- coerce(candidate, ctx) {
3011
- const errorProperty = this.getErrorPropertyFromObject(candidate);
3012
- if (errorProperty) return ctx.apply(errorProperty);
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
+ };
3013
3057
  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
3058
+ flags: featureFlagDetails.featureFlags,
3059
+ payloads: featureFlagDetails.featureFlagPayloads,
3060
+ requestId: featureFlagDetails.requestId
3019
3061
  };
3020
3062
  }
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;
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
+ };
3029
3081
  }
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
- }
3035
- isSeverityLevel(x) {
3036
- return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;
3082
+ return flagsResponse;
3037
3083
  }
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;
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 [];
3042
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 ?? [];
3043
3115
  }
3044
- getObjectClassName(obj) {
3045
- try {
3046
- const prototype = Object.getPrototypeOf(obj);
3047
- return prototype ? prototype.constructor.name : void 0;
3048
- } catch (e) {
3049
- return;
3050
- }
3116
+ get props() {
3117
+ if (!this._props) this._props = this.getPersistedProperty(types_PostHogPersistedProperty.Props);
3118
+ return this._props || {};
3051
3119
  }
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);
3120
+ set props(val) {
3121
+ this._props = val;
3058
3122
  }
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
- };
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
+ });
3067
3131
  }
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);
3132
+ async unregister(property) {
3133
+ this.wrap(() => {
3134
+ delete this.props[property];
3135
+ this.setPersistedProperty(types_PostHogPersistedProperty.Props, this.props);
3136
+ });
3074
3137
  }
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
- };
3138
+ processBeforeEnqueue(message) {
3139
+ return message;
3082
3140
  }
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);
3141
+ async flushStorage() {
3089
3142
  }
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;
3097
- }
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
+ });
3098
3163
  }
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
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
3106
3193
  };
3107
- return ctx.apply(reason);
3108
- }
3109
- getUnhandledRejectionReason(error) {
3110
3194
  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 {
3195
+ const response = await this.fetchWithRetry(url, fetchOptions);
3196
+ await response.body?.cancel()?.catch(() => {
3197
+ });
3198
+ } catch (err) {
3199
+ this._events.emit("error", err);
3114
3200
  }
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
3201
  }
3132
- set(key, value) {
3133
- this._cache.set(key, value);
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;
3134
3216
  }
3135
- reduce() {
3136
- while (this._cache.size >= this._maxSize) {
3137
- const value = this._cache.keys().next().value;
3138
- if (value) this._cache.delete(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;
3139
3227
  }
3140
- }
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;
3228
+ if (message.distinctId) {
3229
+ message.distinct_id = message.distinctId;
3230
+ delete message.distinctId;
3175
3231
  }
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();
3232
+ return message;
3193
3233
  }
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
3202
- });
3203
- this._totalBytes += bytes;
3204
- this._trimToMaxBytes();
3234
+ clearFlushTimer() {
3235
+ if (this._flushTimer) {
3236
+ clearTimeout(this._flushTimer);
3237
+ this._flushTimer = void 0;
3238
+ }
3205
3239
  }
3206
- getAttachable() {
3207
- return this._entries.map((e) => e.step);
3240
+ flushBackground() {
3241
+ this.flush().catch(async (err) => {
3242
+ await logFlushError(err);
3243
+ });
3208
3244
  }
3209
- clear() {
3210
- this._entries = [];
3211
- this._totalBytes = 0;
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;
3212
3258
  }
3213
- size() {
3214
- return this._entries.length;
3259
+ getCustomHeaders() {
3260
+ const customUserAgent = this.getCustomUserAgent();
3261
+ const headers = {};
3262
+ if (customUserAgent && "" !== customUserAgent) headers["User-Agent"] = customUserAgent;
3263
+ return headers;
3215
3264
  }
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;
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);
3220
3324
  }
3325
+ this._events.emit("flush", sentMessages);
3221
3326
  }
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
3327
+ async _sendLogsBatch(payload) {
3328
+ if (this.disabled) return {
3329
+ kind: "fatal",
3330
+ error: new Error("The client is disabled")
3243
3331
  };
3244
- } catch {
3245
- return;
3246
- }
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
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
3345
+ };
3346
+ try {
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"
3259
3355
  };
3260
- if (replacementValue && "object" == typeof replacementValue) {
3261
- if (seen.has(replacementValue)) return "[Circular]";
3262
- seen.add(replacementValue);
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
+ };
3368
+ }
3369
+ }
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;
3263
3380
  }
3264
- return replacementValue;
3381
+ }
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
3265
3403
  });
3266
- } catch {
3267
- return;
3268
3404
  }
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
- }
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
+ }
3423
+ };
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
+ }
3439
+ }
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;
3444
+ });
3445
+ return this.shutdownPromise;
3446
+ }
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";
@@ -3480,107 +3648,8 @@ function createRelativePathModifier(basePath = process.cwd()) {
3480
3648
  };
3481
3649
  }
3482
3650
 
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
- }));
3513
- }
3514
-
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));
3553
- }
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
- };
3581
-
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
@@ -5797,7 +6028,7 @@ var FAILURE_SPAWN_CODE_SET = new Set(FAILURE_SPAWN_CODES);
5797
6028
  import { randomUUID as randomUUID2 } from "node:crypto";
5798
6029
 
5799
6030
  // ../telemetry/src/events.ts
5800
- var PLATFORMS = ["ios", "android", "chromium", "vega"];
6031
+ var PLATFORMS = ["ios", "ios-remote", "android", "chromium", "vega"];
5801
6032
 
5802
6033
  // ../telemetry/src/ai-identity.ts
5803
6034
  var AI_CLIENTS = [
@@ -5993,6 +6224,56 @@ function sanitize(event, raw) {
5993
6224
  // ../telemetry/src/base-props.ts
5994
6225
  import { randomUUID as randomUUID3 } from "node:crypto";
5995
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
+
5996
6277
  // ../../node_modules/ci-info/vendors.json
5997
6278
  var vendors_default = [
5998
6279
  {
@@ -6416,6 +6697,7 @@ function getInvariantProps() {
6416
6697
  arch: process.arch,
6417
6698
  is_tty: Boolean(process.stdout.isTTY),
6418
6699
  is_ci: isCi(),
6700
+ cloud_agent: detectCloudAgent(),
6419
6701
  $process_person_profile: false
6420
6702
  };
6421
6703
  }
@@ -6545,7 +6827,7 @@ function readConfigObject() {
6545
6827
  }
6546
6828
  return {};
6547
6829
  }
6548
- var LOCK_STALE_MS = 1e4;
6830
+ var LOCK_STALE_MS2 = 1e4;
6549
6831
  var LOCK_MAX_WAIT_MS = 2e3;
6550
6832
  var LOCK_RETRY_MS = 25;
6551
6833
  function sleepSync(ms) {
@@ -6566,7 +6848,7 @@ function acquireConfigLock() {
6566
6848
  } catch (err) {
6567
6849
  if (err.code !== "EEXIST") return null;
6568
6850
  try {
6569
- if (Date.now() - fs3.statSync(lockPath).mtimeMs > LOCK_STALE_MS) {
6851
+ if (Date.now() - fs3.statSync(lockPath).mtimeMs > LOCK_STALE_MS2) {
6570
6852
  fs3.unlinkSync(lockPath);
6571
6853
  continue;
6572
6854
  }
@@ -7638,6 +7920,9 @@ async function runDetached(paths, port, host, idleTimeoutMinutes, token) {
7638
7920
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
7639
7921
  bundlePath: paths.bundlePath,
7640
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",
7641
7926
  ...token ? { token } : {}
7642
7927
  });
7643
7928
  const url = formatUrl(host, actualPort);
@@ -7678,6 +7963,8 @@ async function runForeground(paths, port, host, idleTimeoutMinutes, token) {
7678
7963
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
7679
7964
  bundlePath: paths.bundlePath,
7680
7965
  host,
7966
+ // See runDetached: tag CLI-started servers so auto-spawn won't kill them.
7967
+ managed: "cli",
7681
7968
  ...token ? { token } : {}
7682
7969
  });
7683
7970
  stateWritten = true;
@@ -8765,7 +9052,7 @@ var n = class extends V {
8765
9052
  import { styleText as styleText2, stripVTControlCharacters } from "node:util";
8766
9053
  import process$1 from "node:process";
8767
9054
  var import_sisteransi2 = __toESM(require_src(), 1);
8768
- 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";
8769
9056
  import { dirname as dirname5, join as join9 } from "node:path";
8770
9057
  function isUnicodeSupported() {
8771
9058
  if (process$1.platform !== "win32") {
@@ -8775,7 +9062,7 @@ function isUnicodeSupported() {
8775
9062
  }
8776
9063
  var unicode = isUnicodeSupported();
8777
9064
  var isCI = () => process.env.CI === "true";
8778
- var unicodeOr = (e, o2) => unicode ? e : o2;
9065
+ var unicodeOr = (o2, e) => unicode ? o2 : e;
8779
9066
  var S_STEP_ACTIVE = unicodeOr("\u25C6", "*");
8780
9067
  var S_STEP_CANCEL = unicodeOr("\u25A0", "x");
8781
9068
  var S_STEP_ERROR = unicodeOr("\u25B2", "x");
@@ -8801,8 +9088,8 @@ var S_INFO = unicodeOr("\u25CF", "\u2022");
8801
9088
  var S_SUCCESS = unicodeOr("\u25C6", "*");
8802
9089
  var S_WARN = unicodeOr("\u25B2", "!");
8803
9090
  var S_ERROR = unicodeOr("\u25A0", "x");
8804
- var symbol = (e) => {
8805
- switch (e) {
9091
+ var symbol = (o2) => {
9092
+ switch (o2) {
8806
9093
  case "initial":
8807
9094
  case "active":
8808
9095
  return styleText2("cyan", S_STEP_ACTIVE);
@@ -8814,8 +9101,8 @@ var symbol = (e) => {
8814
9101
  return styleText2("green", S_STEP_SUBMIT);
8815
9102
  }
8816
9103
  };
8817
- var symbolBar = (e) => {
8818
- switch (e) {
9104
+ var symbolBar = (o2) => {
9105
+ switch (o2) {
8819
9106
  case "initial":
8820
9107
  case "active":
8821
9108
  return styleText2("cyan", S_BAR);
@@ -8827,6 +9114,10 @@ var symbolBar = (e) => {
8827
9114
  return styleText2("green", S_BAR);
8828
9115
  }
8829
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
+ }
8830
9121
  var E$1 = (l2, o2, g, c2, h2, O = false) => {
8831
9122
  let r2 = o2, w = 0;
8832
9123
  if (O)
@@ -8929,6 +9220,11 @@ ${g}
8929
9220
  }
8930
9221
  }).prompt();
8931
9222
  };
9223
+ var MULTISELECT_INSTRUCTIONS = [
9224
+ `${styleText2("dim", "\u2191/\u2193")} to navigate`,
9225
+ `${styleText2("dim", "Space:")} select`,
9226
+ `${styleText2("dim", "Enter:")} confirm`
9227
+ ];
8932
9228
  var log = {
8933
9229
  message: (s = [], {
8934
9230
  symbol: e = styleText2("gray", S_BAR),
@@ -9075,20 +9371,24 @@ var u2 = {
9075
9371
  heavy: unicodeOr("\u2501", "="),
9076
9372
  block: unicodeOr("\u2588", "#")
9077
9373
  };
9078
- var c = (e, a2) => e.includes(`
9079
- `) ? e.split(`
9080
- `).map((t2) => a2(t2)).join(`
9081
- `) : a2(e);
9082
- var select = (e) => {
9083
- const a2 = (t2, d) => {
9084
- const s = t2.label ?? String(t2.value);
9085
- 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) {
9086
9386
  case "disabled":
9087
- 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"})`)}` : ""}`;
9088
9388
  case "selected":
9089
9389
  return `${c(s, (n2) => styleText2("dim", n2))}`;
9090
9390
  case "active":
9091
- 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})`)}` : ""}`;
9092
9392
  case "cancelled":
9093
9393
  return `${c(s, (n2) => styleText2(["strikethrough", "dim"], n2))}`;
9094
9394
  default:
@@ -9096,52 +9396,53 @@ var select = (e) => {
9096
9396
  }
9097
9397
  };
9098
9398
  return new a({
9099
- options: e.options,
9100
- signal: e.signal,
9101
- input: e.input,
9102
- output: e.output,
9103
- initialValue: e.initialValue,
9399
+ options: t2.options,
9400
+ signal: t2.signal,
9401
+ input: t2.input,
9402
+ output: t2.output,
9403
+ initialValue: t2.initialValue,
9104
9404
  render() {
9105
- const t2 = e.withGuide ?? settings.withGuide, d = `${symbol(this.state)} `, s = `${symbolBar(this.state)} `, n2 = wrapTextWithPrefix(
9106
- e.output,
9107
- 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,
9108
9408
  s,
9109
- d
9110
- ), u3 = `${t2 ? `${styleText2("gray", S_BAR)}
9409
+ m
9410
+ ), u3 = `${i2 ? `${styleText2("gray", S_BAR)}
9111
9411
  ` : ""}${n2}
9112
9412
  `;
9113
9413
  switch (this.state) {
9114
9414
  case "submit": {
9115
- const r2 = t2 ? `${styleText2("gray", S_BAR)} ` : "", l2 = wrapTextWithPrefix(
9116
- e.output,
9415
+ const r2 = i2 ? `${styleText2("gray", S_BAR)} ` : "", o2 = wrapTextWithPrefix(
9416
+ t2.output,
9117
9417
  a2(this.options[this.cursor], "selected"),
9118
9418
  r2
9119
9419
  );
9120
- return `${u3}${l2}`;
9420
+ return `${u3}${o2}`;
9121
9421
  }
9122
9422
  case "cancel": {
9123
- const r2 = t2 ? `${styleText2("gray", S_BAR)} ` : "", l2 = wrapTextWithPrefix(
9124
- e.output,
9423
+ const r2 = i2 ? `${styleText2("gray", S_BAR)} ` : "", o2 = wrapTextWithPrefix(
9424
+ t2.output,
9125
9425
  a2(this.options[this.cursor], "cancelled"),
9126
9426
  r2
9127
9427
  );
9128
- return `${u3}${l2}${t2 ? `
9428
+ return `${u3}${o2}${i2 ? `
9129
9429
  ${styleText2("gray", S_BAR)}` : ""}`;
9130
9430
  }
9131
9431
  default: {
9132
- const r2 = t2 ? `${styleText2("cyan", S_BAR)} ` : "", l2 = t2 ? styleText2("cyan", S_BAR_END) : "", g = u3.split(`
9133
- `).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;
9134
9435
  return `${u3}${r2}${limitOptions({
9135
- output: e.output,
9436
+ output: t2.output,
9136
9437
  cursor: this.cursor,
9137
9438
  options: this.options,
9138
- maxItems: e.maxItems,
9439
+ maxItems: t2.maxItems,
9139
9440
  columnPadding: r2.length,
9140
- rowPadding: g + h2,
9141
- 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")
9142
9443
  }).join(`
9143
9444
  ${r2}`)}
9144
- ${l2}
9445
+ ${h2}
9145
9446
  `;
9146
9447
  }
9147
9448
  }
@@ -9432,6 +9733,8 @@ async function preflightHealth(url, token) {
9432
9733
  signal: controller.signal,
9433
9734
  headers: token ? { Authorization: `Bearer ${token}` } : {}
9434
9735
  });
9736
+ await res.body?.cancel().catch(() => {
9737
+ });
9435
9738
  if (!res.ok) {
9436
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" : "";
9437
9740
  return { ok: false, error: `${res.status} ${res.statusText}${hint}` };