@fogg/bug-reporter 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,6 +50,36 @@ Enable these flags in config to attach logs and request traces to each report:
50
50
  />
51
51
  ```
52
52
 
53
+ ## S3 Storage Example
54
+
55
+ Use this when your backend returns presigned upload URLs.
56
+
57
+ ```tsx
58
+ import { BugReporter } from "@fogg/bug-reporter";
59
+ import "@fogg/bug-reporter/styles.css";
60
+
61
+ export function App() {
62
+ return (
63
+ <BugReporter
64
+ config={{
65
+ apiEndpoint: "https://api.example.com/bug-reports",
66
+ projectId: "web-app",
67
+ environment: "production",
68
+ storage: {
69
+ mode: "s3-presigned",
70
+ s3: {
71
+ presignEndpoint: "https://api.example.com/bug-assets/presign",
72
+ publicBaseUrl: "https://cdn.example.com"
73
+ }
74
+ }
75
+ }}
76
+ />
77
+ );
78
+ }
79
+ ```
80
+
81
+ See `docs/backend-s3.md` for the backend request/response contract.
82
+
53
83
  ## Docs
54
84
 
55
85
  - `docs/quickstart.md`
package/dist/index.cjs CHANGED
@@ -22,12 +22,13 @@ function detectBrowserAndOS(userAgent) {
22
22
 
23
23
  // src/diagnostics/collect.ts
24
24
  function getUserAgentDataSnapshot() {
25
+ var _a;
25
26
  const userAgentData = navigator.userAgentData;
26
27
  if (!userAgentData) {
27
28
  return void 0;
28
29
  }
29
30
  return {
30
- brands: userAgentData.brands?.map((item) => ({
31
+ brands: (_a = userAgentData.brands) == null ? void 0 : _a.map((item) => ({
31
32
  brand: item.brand,
32
33
  version: item.version
33
34
  })),
@@ -56,12 +57,12 @@ function collectDiagnostics(config, options) {
56
57
  appVersion: config.appVersion,
57
58
  environment: config.environment,
58
59
  projectId: config.projectId,
59
- logs: options?.logs,
60
- requests: options?.requests,
60
+ logs: options == null ? void 0 : options.logs,
61
+ requests: options == null ? void 0 : options.requests,
61
62
  navigationTiming: {
62
- domComplete: nav?.domComplete,
63
- loadEventEnd: nav?.loadEventEnd,
64
- responseEnd: nav?.responseEnd
63
+ domComplete: nav == null ? void 0 : nav.domComplete,
64
+ loadEventEnd: nav == null ? void 0 : nav.loadEventEnd,
65
+ responseEnd: nav == null ? void 0 : nav.responseEnd
65
66
  }
66
67
  };
67
68
  }
@@ -74,7 +75,8 @@ var ConsoleBuffer = class {
74
75
  chunk6TCI6T2U_cjs.__publicField(this, "originals", /* @__PURE__ */ new Map());
75
76
  chunk6TCI6T2U_cjs.__publicField(this, "installed", false);
76
77
  chunk6TCI6T2U_cjs.__publicField(this, "onWindowError", (event) => {
77
- this.push("error", [event.message, event.error instanceof Error ? event.error.stack ?? "" : ""]);
78
+ var _a;
79
+ this.push("error", [event.message, event.error instanceof Error ? (_a = event.error.stack) != null ? _a : "" : ""]);
78
80
  });
79
81
  chunk6TCI6T2U_cjs.__publicField(this, "onUnhandledRejection", (event) => {
80
82
  this.push("error", ["Unhandled promise rejection", event.reason]);
@@ -126,7 +128,7 @@ var ConsoleBuffer = class {
126
128
  }
127
129
  try {
128
130
  return JSON.stringify(arg);
129
- } catch {
131
+ } catch (e) {
130
132
  return String(arg);
131
133
  }
132
134
  }).join(" ");
@@ -153,7 +155,7 @@ function extractUrl(input) {
153
155
  return input.url;
154
156
  }
155
157
  function extractMethod(input, init) {
156
- if (init?.method) {
158
+ if (init == null ? void 0 : init.method) {
157
159
  return String(init.method).toUpperCase();
158
160
  }
159
161
  if (typeof Request !== "undefined" && input instanceof Request) {
@@ -243,15 +245,17 @@ var NetworkBuffer = class {
243
245
  this.originalXhrSend = XMLHttpRequest.prototype.send;
244
246
  const buffer = this;
245
247
  XMLHttpRequest.prototype.open = function patchedOpen(method, url, async, username, password) {
248
+ var _a;
246
249
  xhrMeta.set(this, {
247
250
  method: String(method || "GET").toUpperCase(),
248
251
  url: String(url),
249
252
  startedAt: 0,
250
253
  timestamp: ""
251
254
  });
252
- buffer.originalXhrOpen?.call(this, method, url, async ?? true, username ?? null, password ?? null);
255
+ (_a = buffer.originalXhrOpen) == null ? void 0 : _a.call(this, method, url, async != null ? async : true, username != null ? username : null, password != null ? password : null);
253
256
  };
254
257
  XMLHttpRequest.prototype.send = function patchedSend(body) {
258
+ var _a;
255
259
  const existing = xhrMeta.get(this);
256
260
  if (existing) {
257
261
  existing.startedAt = performance.now();
@@ -297,7 +301,7 @@ var NetworkBuffer = class {
297
301
  this.addEventListener("loadend", onLoadEnd);
298
302
  this.addEventListener("error", onError);
299
303
  }
300
- buffer.originalXhrSend?.call(this, body);
304
+ (_a = buffer.originalXhrSend) == null ? void 0 : _a.call(this, body);
301
305
  };
302
306
  }
303
307
  push(entry) {
@@ -315,53 +319,54 @@ var DEFAULT_MASK_SELECTORS = [
315
319
  "[data-bug-reporter-mask='true']"
316
320
  ];
317
321
  function withDefaults(config) {
322
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V;
318
323
  return {
319
324
  apiEndpoint: config.apiEndpoint,
320
325
  projectId: config.projectId,
321
326
  appVersion: config.appVersion,
322
327
  environment: config.environment,
323
328
  storage: {
324
- mode: config.storage?.mode ?? "proxy",
325
- s3: config.storage?.s3,
326
- local: config.storage?.local,
327
- proxy: config.storage?.proxy,
329
+ mode: (_b = (_a = config.storage) == null ? void 0 : _a.mode) != null ? _b : "proxy",
330
+ s3: (_c = config.storage) == null ? void 0 : _c.s3,
331
+ local: (_d = config.storage) == null ? void 0 : _d.local,
332
+ proxy: (_e = config.storage) == null ? void 0 : _e.proxy,
328
333
  limits: {
329
- maxVideoSeconds: config.storage?.limits?.maxVideoSeconds ?? 30,
330
- maxVideoBytes: config.storage?.limits?.maxVideoBytes ?? 50 * 1024 * 1024,
331
- maxScreenshotBytes: config.storage?.limits?.maxScreenshotBytes ?? 8 * 1024 * 1024
334
+ maxVideoSeconds: (_h = (_g = (_f = config.storage) == null ? void 0 : _f.limits) == null ? void 0 : _g.maxVideoSeconds) != null ? _h : 30,
335
+ maxVideoBytes: (_k = (_j = (_i = config.storage) == null ? void 0 : _i.limits) == null ? void 0 : _j.maxVideoBytes) != null ? _k : 50 * 1024 * 1024,
336
+ maxScreenshotBytes: (_n = (_m = (_l = config.storage) == null ? void 0 : _l.limits) == null ? void 0 : _m.maxScreenshotBytes) != null ? _n : 8 * 1024 * 1024
332
337
  }
333
338
  },
334
339
  auth: {
335
- headers: config.auth?.headers ?? {},
336
- withCredentials: config.auth?.withCredentials ?? false
340
+ headers: (_p = (_o = config.auth) == null ? void 0 : _o.headers) != null ? _p : {},
341
+ withCredentials: (_r = (_q = config.auth) == null ? void 0 : _q.withCredentials) != null ? _r : false
337
342
  },
338
343
  theme: {
339
- primaryColor: config.theme?.primaryColor ?? "#1b74e4",
340
- position: config.theme?.position ?? "bottom-right",
341
- zIndex: config.theme?.zIndex ?? 2147483e3,
342
- borderRadius: config.theme?.borderRadius ?? "999px"
344
+ primaryColor: (_t = (_s = config.theme) == null ? void 0 : _s.primaryColor) != null ? _t : "#1b74e4",
345
+ position: (_v = (_u = config.theme) == null ? void 0 : _u.position) != null ? _v : "bottom-right",
346
+ zIndex: (_x = (_w = config.theme) == null ? void 0 : _w.zIndex) != null ? _x : 2147483e3,
347
+ borderRadius: (_z = (_y = config.theme) == null ? void 0 : _y.borderRadius) != null ? _z : "999px"
343
348
  },
344
349
  features: {
345
- screenshot: config.features?.screenshot ?? true,
346
- recording: config.features?.recording ?? true,
347
- annotations: config.features?.annotations ?? true,
348
- consoleLogs: config.features?.consoleLogs ?? false,
349
- networkInfo: config.features?.networkInfo ?? false
350
+ screenshot: (_B = (_A = config.features) == null ? void 0 : _A.screenshot) != null ? _B : true,
351
+ recording: (_D = (_C = config.features) == null ? void 0 : _C.recording) != null ? _D : true,
352
+ annotations: (_F = (_E = config.features) == null ? void 0 : _E.annotations) != null ? _F : true,
353
+ consoleLogs: (_H = (_G = config.features) == null ? void 0 : _G.consoleLogs) != null ? _H : false,
354
+ networkInfo: (_J = (_I = config.features) == null ? void 0 : _I.networkInfo) != null ? _J : false
350
355
  },
351
356
  user: config.user,
352
- attributes: config.attributes ?? {},
357
+ attributes: (_K = config.attributes) != null ? _K : {},
353
358
  privacy: {
354
- maskSelectors: config.privacy?.maskSelectors ?? DEFAULT_MASK_SELECTORS,
355
- redactTextPatterns: config.privacy?.redactTextPatterns ?? []
359
+ maskSelectors: (_M = (_L = config.privacy) == null ? void 0 : _L.maskSelectors) != null ? _M : DEFAULT_MASK_SELECTORS,
360
+ redactTextPatterns: (_O = (_N = config.privacy) == null ? void 0 : _N.redactTextPatterns) != null ? _O : []
356
361
  },
357
362
  diagnostics: {
358
- consoleBufferSize: config.diagnostics?.consoleBufferSize ?? 100,
359
- requestBufferSize: config.diagnostics?.requestBufferSize ?? 200
363
+ consoleBufferSize: (_Q = (_P = config.diagnostics) == null ? void 0 : _P.consoleBufferSize) != null ? _Q : 100,
364
+ requestBufferSize: (_S = (_R = config.diagnostics) == null ? void 0 : _R.requestBufferSize) != null ? _S : 200
360
365
  },
361
366
  hooks: {
362
- beforeSubmit: config.hooks?.beforeSubmit,
363
- onSuccess: config.hooks?.onSuccess,
364
- onError: config.hooks?.onError
367
+ beforeSubmit: (_T = config.hooks) == null ? void 0 : _T.beforeSubmit,
368
+ onSuccess: (_U = config.hooks) == null ? void 0 : _U.onSuccess,
369
+ onError: (_V = config.hooks) == null ? void 0 : _V.onError
365
370
  }
366
371
  };
367
372
  }
@@ -381,7 +386,7 @@ var LocalPublicProvider = class {
381
386
  }));
382
387
  }
383
388
  async upload(instruction, blob, onProgress) {
384
- onProgress?.(0);
389
+ onProgress == null ? void 0 : onProgress(0);
385
390
  const form = new FormData();
386
391
  form.append("file", blob, instruction.id);
387
392
  form.append("id", instruction.id);
@@ -396,7 +401,7 @@ var LocalPublicProvider = class {
396
401
  throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `Local upload failed (${response.status}).`);
397
402
  }
398
403
  const payload = await response.json();
399
- onProgress?.(1);
404
+ onProgress == null ? void 0 : onProgress(1);
400
405
  return {
401
406
  id: instruction.id,
402
407
  type: instruction.type,
@@ -423,7 +428,7 @@ var ProxyProvider = class {
423
428
  }));
424
429
  }
425
430
  async upload(instruction, blob, onProgress) {
426
- onProgress?.(0);
431
+ onProgress == null ? void 0 : onProgress(0);
427
432
  const response = await fetch(instruction.uploadUrl, {
428
433
  method: "POST",
429
434
  headers: {
@@ -439,7 +444,7 @@ var ProxyProvider = class {
439
444
  throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `Proxy upload failed (${response.status}).`);
440
445
  }
441
446
  const payload = await response.json();
442
- onProgress?.(1);
447
+ onProgress == null ? void 0 : onProgress(1);
443
448
  return {
444
449
  id: instruction.id,
445
450
  type: instruction.type,
@@ -457,6 +462,7 @@ var S3PresignedProvider = class {
457
462
  this.options = options;
458
463
  }
459
464
  async prepareUploads(files) {
465
+ var _a;
460
466
  const response = await fetch(this.options.presignEndpoint, {
461
467
  method: "POST",
462
468
  headers: {
@@ -470,13 +476,14 @@ var S3PresignedProvider = class {
470
476
  throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `Failed to prepare uploads (${response.status}).`);
471
477
  }
472
478
  const payload = await response.json();
473
- if (!payload.uploads?.length) {
479
+ if (!((_a = payload.uploads) == null ? void 0 : _a.length)) {
474
480
  throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", "Presign endpoint did not return upload instructions.");
475
481
  }
476
482
  return payload.uploads;
477
483
  }
478
484
  async upload(instruction, blob, onProgress) {
479
- onProgress?.(0);
485
+ var _a;
486
+ onProgress == null ? void 0 : onProgress(0);
480
487
  if (instruction.method === "POST" && instruction.fields) {
481
488
  const formData = new FormData();
482
489
  Object.entries(instruction.fields).forEach(([key, value]) => formData.append(key, value));
@@ -498,8 +505,8 @@ var S3PresignedProvider = class {
498
505
  throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `S3 upload failed (${response.status}).`);
499
506
  }
500
507
  }
501
- onProgress?.(1);
502
- const publicUrl = instruction.publicUrl ?? (this.options.publicBaseUrl && instruction.key ? `${this.options.publicBaseUrl.replace(/\/$/, "")}/${instruction.key}` : instruction.uploadUrl);
508
+ onProgress == null ? void 0 : onProgress(1);
509
+ const publicUrl = (_a = instruction.publicUrl) != null ? _a : this.options.publicBaseUrl && instruction.key ? `${this.options.publicBaseUrl.replace(/\/$/, "")}/${instruction.key}` : instruction.uploadUrl;
503
510
  return {
504
511
  id: instruction.id,
505
512
  type: instruction.type,
@@ -513,31 +520,32 @@ var S3PresignedProvider = class {
513
520
 
514
521
  // src/storage/factory.ts
515
522
  function createStorageProvider(config) {
523
+ var _a, _b, _c, _d, _e;
516
524
  if (config.storage.mode === "s3-presigned") {
517
- const presignEndpoint = config.storage.s3?.presignEndpoint;
525
+ const presignEndpoint = (_a = config.storage.s3) == null ? void 0 : _a.presignEndpoint;
518
526
  if (!presignEndpoint) {
519
527
  throw new Error("storage.s3.presignEndpoint is required for s3-presigned mode.");
520
528
  }
521
529
  return new S3PresignedProvider({
522
530
  presignEndpoint,
523
- publicBaseUrl: config.storage.s3?.publicBaseUrl,
531
+ publicBaseUrl: (_b = config.storage.s3) == null ? void 0 : _b.publicBaseUrl,
524
532
  authHeaders: config.auth.headers,
525
533
  withCredentials: config.auth.withCredentials
526
534
  });
527
535
  }
528
536
  if (config.storage.mode === "local-public") {
529
- const uploadEndpoint2 = config.storage.local?.uploadEndpoint;
537
+ const uploadEndpoint2 = (_c = config.storage.local) == null ? void 0 : _c.uploadEndpoint;
530
538
  if (!uploadEndpoint2) {
531
539
  throw new Error("storage.local.uploadEndpoint is required for local-public mode.");
532
540
  }
533
541
  return new LocalPublicProvider({
534
542
  uploadEndpoint: uploadEndpoint2,
535
- publicBaseUrl: config.storage.local?.publicBaseUrl,
543
+ publicBaseUrl: (_d = config.storage.local) == null ? void 0 : _d.publicBaseUrl,
536
544
  authHeaders: config.auth.headers,
537
545
  withCredentials: config.auth.withCredentials
538
546
  });
539
547
  }
540
- const uploadEndpoint = config.storage.proxy?.uploadEndpoint;
548
+ const uploadEndpoint = (_e = config.storage.proxy) == null ? void 0 : _e.uploadEndpoint;
541
549
  if (!uploadEndpoint) {
542
550
  throw new Error("storage.proxy.uploadEndpoint is required for proxy mode.");
543
551
  }
@@ -581,6 +589,7 @@ async function withRetry(fn, retries) {
581
589
  throw lastError;
582
590
  }
583
591
  async function uploadAssets(options) {
592
+ var _a, _b;
584
593
  const files = options.assets.map((asset) => ({
585
594
  id: asset.id,
586
595
  name: asset.filename,
@@ -599,20 +608,22 @@ async function uploadAssets(options) {
599
608
  }
600
609
  const ref = await withRetry(
601
610
  () => options.provider.upload(instruction, asset.blob, (inner) => {
611
+ var _a2;
602
612
  const aggregate = (completed + inner) / options.assets.length;
603
- options.onProgress?.(aggregate);
613
+ (_a2 = options.onProgress) == null ? void 0 : _a2.call(options, aggregate);
604
614
  }),
605
- options.retries ?? 2
615
+ (_a = options.retries) != null ? _a : 2
606
616
  );
607
617
  refs.push(ref);
608
618
  completed += 1;
609
- options.onProgress?.(completed / options.assets.length);
619
+ (_b = options.onProgress) == null ? void 0 : _b.call(options, completed / options.assets.length);
610
620
  }
611
621
  return refs;
612
622
  }
613
623
 
614
624
  // src/core/submit.ts
615
625
  async function submitReport(options) {
626
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
616
627
  const provider = createStorageProvider(options.config);
617
628
  const assetReferences = await uploadAssets({
618
629
  provider,
@@ -649,12 +660,12 @@ async function submitReport(options) {
649
660
  requests: options.diagnostics.requests
650
661
  },
651
662
  reporter: {
652
- id: options.config.user?.id,
653
- name: options.config.user?.name,
654
- email: options.config.user?.email,
655
- role: options.config.user?.role,
656
- ip: options.config.user?.ip,
657
- anonymous: options.config.user?.anonymous ?? !(options.config.user?.id || options.config.user?.email || options.config.user?.name)
663
+ id: (_a = options.config.user) == null ? void 0 : _a.id,
664
+ name: (_b = options.config.user) == null ? void 0 : _b.name,
665
+ email: (_c = options.config.user) == null ? void 0 : _c.email,
666
+ role: (_d = options.config.user) == null ? void 0 : _d.role,
667
+ ip: (_e = options.config.user) == null ? void 0 : _e.ip,
668
+ anonymous: (_j = (_f = options.config.user) == null ? void 0 : _f.anonymous) != null ? _j : !(((_g = options.config.user) == null ? void 0 : _g.id) || ((_h = options.config.user) == null ? void 0 : _h.email) || ((_i = options.config.user) == null ? void 0 : _i.name))
658
669
  },
659
670
  attributes: options.attributes
660
671
  };
@@ -729,6 +740,7 @@ function BugReporterProvider({ config, children }) {
729
740
  }));
730
741
  }, []);
731
742
  const reset = react.useCallback(() => {
743
+ var _a, _b;
732
744
  setSessionActive(false);
733
745
  setState((prev) => {
734
746
  resetAssets(prev.assets);
@@ -739,8 +751,8 @@ function BugReporterProvider({ config, children }) {
739
751
  isOpen: prev.isOpen
740
752
  };
741
753
  });
742
- consoleBufferRef.current?.clear();
743
- networkBufferRef.current?.clear();
754
+ (_a = consoleBufferRef.current) == null ? void 0 : _a.clear();
755
+ (_b = networkBufferRef.current) == null ? void 0 : _b.clear();
744
756
  }, [resetAssets, resolvedConfig.attributes]);
745
757
  const setStep = react.useCallback((step) => {
746
758
  setState((prev) => ({ ...prev, step }));
@@ -792,6 +804,7 @@ function BugReporterProvider({ config, children }) {
792
804
  setAssetByType("recording", asset);
793
805
  }, [setAssetByType]);
794
806
  const submit = react.useCallback(async () => {
807
+ var _a, _b, _c, _d, _e, _f;
795
808
  setState((prev) => ({
796
809
  ...prev,
797
810
  step: "submitting",
@@ -800,8 +813,8 @@ function BugReporterProvider({ config, children }) {
800
813
  error: void 0
801
814
  }));
802
815
  try {
803
- const logs = resolvedConfig.features.consoleLogs ? consoleBufferRef.current?.snapshot() : void 0;
804
- const requests = resolvedConfig.features.networkInfo ? networkBufferRef.current?.snapshot() : void 0;
816
+ const logs = resolvedConfig.features.consoleLogs ? (_a = consoleBufferRef.current) == null ? void 0 : _a.snapshot() : void 0;
817
+ const requests = resolvedConfig.features.networkInfo ? (_b = networkBufferRef.current) == null ? void 0 : _b.snapshot() : void 0;
805
818
  const diagnostics = collectDiagnostics(resolvedConfig, {
806
819
  logs,
807
820
  requests
@@ -823,7 +836,7 @@ function BugReporterProvider({ config, children }) {
823
836
  uploadProgress: 1,
824
837
  step: "success"
825
838
  }));
826
- resolvedConfig.hooks.onSuccess?.(response);
839
+ (_d = (_c = resolvedConfig.hooks).onSuccess) == null ? void 0 : _d.call(_c, response);
827
840
  } catch (error) {
828
841
  const message = error instanceof Error ? error.message : "Unexpected submit failure.";
829
842
  setState((prev) => ({
@@ -832,18 +845,22 @@ function BugReporterProvider({ config, children }) {
832
845
  step: "review",
833
846
  error: message
834
847
  }));
835
- resolvedConfig.hooks.onError?.(error);
848
+ (_f = (_e = resolvedConfig.hooks).onError) == null ? void 0 : _f.call(_e, error);
836
849
  }
837
850
  }, [resolvedConfig, state.assets, state.attributes, state.draft]);
838
851
  const retrySubmit = react.useCallback(async () => {
839
852
  await submit();
840
853
  }, [submit]);
841
854
  const getDiagnosticsPreview = react.useCallback(() => {
842
- const logs = resolvedConfig.features.consoleLogs ? consoleBufferRef.current?.snapshot() ?? [] : [];
843
- const requests = resolvedConfig.features.networkInfo ? networkBufferRef.current?.snapshot() ?? [] : [];
855
+ var _a, _b, _c, _d;
856
+ const logs = resolvedConfig.features.consoleLogs ? (_b = (_a = consoleBufferRef.current) == null ? void 0 : _a.snapshot()) != null ? _b : [] : [];
857
+ const requests = resolvedConfig.features.networkInfo ? (_d = (_c = networkBufferRef.current) == null ? void 0 : _c.snapshot()) != null ? _d : [] : [];
844
858
  return {
845
859
  errorLogs: logs.filter((entry) => entry.level === "error"),
846
- failedRequests: requests.filter((request) => Boolean(request.error) || request.ok === false || (request.status ?? 0) >= 400)
860
+ failedRequests: requests.filter((request) => {
861
+ var _a2;
862
+ return Boolean(request.error) || request.ok === false || ((_a2 = request.status) != null ? _a2 : 0) >= 400;
863
+ })
847
864
  };
848
865
  }, [resolvedConfig.features.consoleLogs, resolvedConfig.features.networkInfo]);
849
866
  react.useEffect(() => {
@@ -863,8 +880,8 @@ function BugReporterProvider({ config, children }) {
863
880
  networkBufferRef.current = networkBuffer;
864
881
  }
865
882
  return () => {
866
- consoleBuffer?.uninstall();
867
- networkBuffer?.uninstall();
883
+ consoleBuffer == null ? void 0 : consoleBuffer.uninstall();
884
+ networkBuffer == null ? void 0 : networkBuffer.uninstall();
868
885
  consoleBufferRef.current = null;
869
886
  networkBufferRef.current = null;
870
887
  };
@@ -880,9 +897,10 @@ function BugReporterProvider({ config, children }) {
880
897
  }, [state.assets]);
881
898
  react.useEffect(() => {
882
899
  return () => {
900
+ var _a, _b;
883
901
  resetAssets(assetsRef.current);
884
- consoleBufferRef.current?.uninstall();
885
- networkBufferRef.current?.uninstall();
902
+ (_a = consoleBufferRef.current) == null ? void 0 : _a.uninstall();
903
+ (_b = networkBufferRef.current) == null ? void 0 : _b.uninstall();
886
904
  };
887
905
  }, [resetAssets]);
888
906
  const value = react.useMemo(
@@ -946,7 +964,7 @@ function useFocusTrap(enabled, containerRef) {
946
964
  const focusable = getFocusable(container);
947
965
  const first = focusable[0];
948
966
  const last = focusable[focusable.length - 1];
949
- first?.focus();
967
+ first == null ? void 0 : first.focus();
950
968
  const onKeyDown = (event) => {
951
969
  if (event.key !== "Tab") {
952
970
  return;
@@ -1289,9 +1307,10 @@ var inlineStyles = {
1289
1307
  }
1290
1308
  };
1291
1309
  function getButtonStyle(variant, options) {
1292
- const disabled = options?.disabled ?? false;
1293
- const active = options?.active ?? false;
1294
- const fullWidth = options?.fullWidth ?? false;
1310
+ var _a, _b, _c;
1311
+ const disabled = (_a = options == null ? void 0 : options.disabled) != null ? _a : false;
1312
+ const active = (_b = options == null ? void 0 : options.active) != null ? _b : false;
1313
+ const fullWidth = (_c = options == null ? void 0 : options.fullWidth) != null ? _c : false;
1295
1314
  const base = {
1296
1315
  border: "1px solid transparent",
1297
1316
  borderRadius: "10px",
@@ -1329,6 +1348,7 @@ function getDockButtonStyle(isActive) {
1329
1348
 
1330
1349
  // src/components/LauncherButton.tsx
1331
1350
  function LauncherButton({ position, text, themeMode = "dark", buttonColor }) {
1351
+ var _a;
1332
1352
  const {
1333
1353
  config,
1334
1354
  state: { isOpen },
@@ -1337,9 +1357,9 @@ function LauncherButton({ position, text, themeMode = "dark", buttonColor }) {
1337
1357
  if (isOpen) {
1338
1358
  return null;
1339
1359
  }
1340
- const resolvedPosition = position ?? config.theme.position ?? "bottom-right";
1341
- const label = text ?? "Get Help";
1342
- const resolvedButtonColor = buttonColor ?? config.theme.primaryColor;
1360
+ const resolvedPosition = (_a = position != null ? position : config.theme.position) != null ? _a : "bottom-right";
1361
+ const label = text != null ? text : "Get Help";
1362
+ const resolvedButtonColor = buttonColor != null ? buttonColor : config.theme.primaryColor;
1343
1363
  const launcherStyle = getLauncherStyle({
1344
1364
  position: resolvedPosition,
1345
1365
  borderRadius: config.theme.borderRadius,
@@ -1387,10 +1407,10 @@ function Modal({ isOpen, dockSide, themeMode, buttonColor, title, zIndex, onRequ
1387
1407
 
1388
1408
  // src/core/lazy.ts
1389
1409
  async function loadScreenshotCapture() {
1390
- return import('./screenshot-FRAZAS6B.cjs');
1410
+ return import('./screenshot-AWRHVVWJ.cjs');
1391
1411
  }
1392
1412
  async function loadScreenRecording() {
1393
- return import('./recording-ML63ZQ6A.cjs');
1413
+ return import('./recording-DZREYVVL.cjs');
1394
1414
  }
1395
1415
 
1396
1416
  // src/core/validation.ts
@@ -1586,6 +1606,7 @@ function notifySubscribers() {
1586
1606
  subscribers.forEach((handler) => handler());
1587
1607
  }
1588
1608
  function StepRecording({ onBack, onNext, embedded = false, compact = false }) {
1609
+ var _a;
1589
1610
  const {
1590
1611
  config,
1591
1612
  state: { assets },
@@ -1595,7 +1616,7 @@ function StepRecording({ onBack, onNext, embedded = false, compact = false }) {
1595
1616
  const activeRef = react.useRef(null);
1596
1617
  const mountedRef = react.useRef(true);
1597
1618
  const [isRecording, setIsRecording] = react.useState(Boolean(sharedRecording));
1598
- const [seconds, setSeconds] = react.useState(sharedRecording?.seconds ?? 0);
1619
+ const [seconds, setSeconds] = react.useState((_a = sharedRecording == null ? void 0 : sharedRecording.seconds) != null ? _a : 0);
1599
1620
  const [error, setError] = react.useState(null);
1600
1621
  const start = async () => {
1601
1622
  if (sharedRecording) {
@@ -1648,18 +1669,20 @@ function StepRecording({ onBack, onNext, embedded = false, compact = false }) {
1648
1669
  }
1649
1670
  };
1650
1671
  const stop = () => {
1672
+ var _a2;
1651
1673
  if (sharedRecording) {
1652
1674
  sharedRecording.active.stop();
1653
1675
  return;
1654
1676
  }
1655
- activeRef.current?.stop();
1677
+ (_a2 = activeRef.current) == null ? void 0 : _a2.stop();
1656
1678
  };
1657
1679
  react.useEffect(() => {
1658
1680
  mountedRef.current = true;
1659
1681
  const sync = () => {
1660
- activeRef.current = sharedRecording?.active ?? null;
1682
+ var _a2, _b;
1683
+ activeRef.current = (_a2 = sharedRecording == null ? void 0 : sharedRecording.active) != null ? _a2 : null;
1661
1684
  setIsRecording(Boolean(sharedRecording));
1662
- setSeconds(sharedRecording?.seconds ?? 0);
1685
+ setSeconds((_b = sharedRecording == null ? void 0 : sharedRecording.seconds) != null ? _b : 0);
1663
1686
  };
1664
1687
  sync();
1665
1688
  subscribers.add(sync);
@@ -1751,12 +1774,13 @@ function StepDescribe({ onNext, CustomForm }) {
1751
1774
  }
1752
1775
  };
1753
1776
  const continueToNext = async () => {
1777
+ var _a;
1754
1778
  setError(null);
1755
1779
  if (config.features.screenshot && !screenshot) {
1756
1780
  setError("Capture a screenshot to continue.");
1757
1781
  return;
1758
1782
  }
1759
- if (config.features.screenshot && screenshot && config.features.annotations && annotationRef.current?.hasAnnotations()) {
1783
+ if (config.features.screenshot && screenshot && config.features.annotations && ((_a = annotationRef.current) == null ? void 0 : _a.hasAnnotations())) {
1760
1784
  const annotatedBlob = await annotationRef.current.exportBlob();
1761
1785
  validateScreenshotSize(annotatedBlob.size, config.storage.limits.maxScreenshotBytes);
1762
1786
  setScreenshot({
@@ -1939,7 +1963,8 @@ function BugReporter({
1939
1963
  themeMode = "dark",
1940
1964
  buttonColor
1941
1965
  }) {
1942
- const resolvedButtonColor = buttonColor ?? config.theme?.primaryColor ?? "#3b82f6";
1966
+ var _a, _b;
1967
+ const resolvedButtonColor = (_b = buttonColor != null ? buttonColor : (_a = config.theme) == null ? void 0 : _a.primaryColor) != null ? _b : "#3b82f6";
1943
1968
  return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(BugReporterProvider, { config }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
1944
1969
  BugReporterShell,
1945
1970
  {