@bbearai/react-native 0.3.7 → 0.3.8
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/index.js +278 -163
- package/dist/index.mjs +278 -163
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11392,6 +11392,239 @@ function shouldShowDeprecationWarning() {
|
|
|
11392
11392
|
if (shouldShowDeprecationWarning()) console.warn("\u26A0\uFE0F Node.js 18 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 20 or later. For more information, visit: https://github.com/orgs/supabase/discussions/37217");
|
|
11393
11393
|
|
|
11394
11394
|
// ../core/dist/index.mjs
|
|
11395
|
+
var MAX_CONSOLE_LOGS = 50;
|
|
11396
|
+
var MAX_NETWORK_REQUESTS = 20;
|
|
11397
|
+
var MAX_NAVIGATION_HISTORY = 20;
|
|
11398
|
+
var MAX_RESPONSE_BODY_LENGTH = 500;
|
|
11399
|
+
var ContextCaptureManager = class {
|
|
11400
|
+
constructor() {
|
|
11401
|
+
this.consoleLogs = [];
|
|
11402
|
+
this.networkRequests = [];
|
|
11403
|
+
this.navigationHistory = [];
|
|
11404
|
+
this.originalConsole = {};
|
|
11405
|
+
this.isCapturing = false;
|
|
11406
|
+
}
|
|
11407
|
+
/**
|
|
11408
|
+
* Start capturing console logs, network requests, and navigation
|
|
11409
|
+
*/
|
|
11410
|
+
startCapture() {
|
|
11411
|
+
if (this.isCapturing) return;
|
|
11412
|
+
this.isCapturing = true;
|
|
11413
|
+
this.captureConsole();
|
|
11414
|
+
this.captureFetch();
|
|
11415
|
+
this.captureNavigation();
|
|
11416
|
+
}
|
|
11417
|
+
/**
|
|
11418
|
+
* Stop capturing and restore original functions
|
|
11419
|
+
*/
|
|
11420
|
+
stopCapture() {
|
|
11421
|
+
if (!this.isCapturing) return;
|
|
11422
|
+
this.isCapturing = false;
|
|
11423
|
+
if (this.originalConsole.log) console.log = this.originalConsole.log;
|
|
11424
|
+
if (this.originalConsole.warn) console.warn = this.originalConsole.warn;
|
|
11425
|
+
if (this.originalConsole.error) console.error = this.originalConsole.error;
|
|
11426
|
+
if (this.originalConsole.info) console.info = this.originalConsole.info;
|
|
11427
|
+
if (this.originalFetch && typeof window !== "undefined") {
|
|
11428
|
+
window.fetch = this.originalFetch;
|
|
11429
|
+
}
|
|
11430
|
+
if (typeof window !== "undefined" && typeof history !== "undefined") {
|
|
11431
|
+
if (this.originalPushState) {
|
|
11432
|
+
history.pushState = this.originalPushState;
|
|
11433
|
+
}
|
|
11434
|
+
if (this.originalReplaceState) {
|
|
11435
|
+
history.replaceState = this.originalReplaceState;
|
|
11436
|
+
}
|
|
11437
|
+
if (this.popstateHandler) {
|
|
11438
|
+
window.removeEventListener("popstate", this.popstateHandler);
|
|
11439
|
+
}
|
|
11440
|
+
}
|
|
11441
|
+
}
|
|
11442
|
+
/**
|
|
11443
|
+
* Get captured context for a bug report
|
|
11444
|
+
*/
|
|
11445
|
+
getEnhancedContext() {
|
|
11446
|
+
return {
|
|
11447
|
+
consoleLogs: [...this.consoleLogs],
|
|
11448
|
+
networkRequests: [...this.networkRequests],
|
|
11449
|
+
navigationHistory: [...this.navigationHistory],
|
|
11450
|
+
performanceMetrics: this.getPerformanceMetrics(),
|
|
11451
|
+
environment: this.getEnvironmentInfo()
|
|
11452
|
+
};
|
|
11453
|
+
}
|
|
11454
|
+
/**
|
|
11455
|
+
* Get the auto-captured navigation history
|
|
11456
|
+
*/
|
|
11457
|
+
getNavigationHistory() {
|
|
11458
|
+
return [...this.navigationHistory];
|
|
11459
|
+
}
|
|
11460
|
+
/**
|
|
11461
|
+
* Get the current route (last entry in navigation history, or window.location)
|
|
11462
|
+
*/
|
|
11463
|
+
getCurrentRoute() {
|
|
11464
|
+
if (this.navigationHistory.length > 0) {
|
|
11465
|
+
return this.navigationHistory[this.navigationHistory.length - 1];
|
|
11466
|
+
}
|
|
11467
|
+
if (typeof window !== "undefined") {
|
|
11468
|
+
return window.location.pathname;
|
|
11469
|
+
}
|
|
11470
|
+
return "unknown";
|
|
11471
|
+
}
|
|
11472
|
+
/**
|
|
11473
|
+
* Manually track a navigation event (for React Native or custom routing)
|
|
11474
|
+
*/
|
|
11475
|
+
trackNavigation(route) {
|
|
11476
|
+
const last = this.navigationHistory[this.navigationHistory.length - 1];
|
|
11477
|
+
if (route === last) return;
|
|
11478
|
+
this.navigationHistory.push(route);
|
|
11479
|
+
if (this.navigationHistory.length > MAX_NAVIGATION_HISTORY) {
|
|
11480
|
+
this.navigationHistory.shift();
|
|
11481
|
+
}
|
|
11482
|
+
}
|
|
11483
|
+
/**
|
|
11484
|
+
* Clear captured data
|
|
11485
|
+
*/
|
|
11486
|
+
clear() {
|
|
11487
|
+
this.consoleLogs = [];
|
|
11488
|
+
this.networkRequests = [];
|
|
11489
|
+
this.navigationHistory = [];
|
|
11490
|
+
}
|
|
11491
|
+
/**
|
|
11492
|
+
* Add a log entry manually (for custom logging)
|
|
11493
|
+
*/
|
|
11494
|
+
addLog(level, message, args) {
|
|
11495
|
+
this.consoleLogs.push({
|
|
11496
|
+
level,
|
|
11497
|
+
message,
|
|
11498
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11499
|
+
args
|
|
11500
|
+
});
|
|
11501
|
+
if (this.consoleLogs.length > MAX_CONSOLE_LOGS) {
|
|
11502
|
+
this.consoleLogs = this.consoleLogs.slice(-MAX_CONSOLE_LOGS);
|
|
11503
|
+
}
|
|
11504
|
+
}
|
|
11505
|
+
/**
|
|
11506
|
+
* Add a network request manually
|
|
11507
|
+
*/
|
|
11508
|
+
addNetworkRequest(request) {
|
|
11509
|
+
this.networkRequests.push(request);
|
|
11510
|
+
if (this.networkRequests.length > MAX_NETWORK_REQUESTS) {
|
|
11511
|
+
this.networkRequests = this.networkRequests.slice(-MAX_NETWORK_REQUESTS);
|
|
11512
|
+
}
|
|
11513
|
+
}
|
|
11514
|
+
captureConsole() {
|
|
11515
|
+
if (typeof console === "undefined") return;
|
|
11516
|
+
const levels = ["log", "warn", "error", "info"];
|
|
11517
|
+
levels.forEach((level) => {
|
|
11518
|
+
this.originalConsole[level] = console[level];
|
|
11519
|
+
console[level] = (...args) => {
|
|
11520
|
+
this.originalConsole[level]?.apply(console, args);
|
|
11521
|
+
try {
|
|
11522
|
+
const message = args.map((arg) => {
|
|
11523
|
+
if (typeof arg === "string") return arg;
|
|
11524
|
+
try {
|
|
11525
|
+
return JSON.stringify(arg);
|
|
11526
|
+
} catch {
|
|
11527
|
+
return String(arg);
|
|
11528
|
+
}
|
|
11529
|
+
}).join(" ");
|
|
11530
|
+
this.addLog(level, message.slice(0, 500));
|
|
11531
|
+
} catch {
|
|
11532
|
+
}
|
|
11533
|
+
};
|
|
11534
|
+
});
|
|
11535
|
+
}
|
|
11536
|
+
captureFetch() {
|
|
11537
|
+
if (typeof window === "undefined" || typeof fetch === "undefined") return;
|
|
11538
|
+
this.originalFetch = window.fetch;
|
|
11539
|
+
const self2 = this;
|
|
11540
|
+
window.fetch = async function(input, init) {
|
|
11541
|
+
const startTime = Date.now();
|
|
11542
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
11543
|
+
const method = init?.method || "GET";
|
|
11544
|
+
try {
|
|
11545
|
+
const response = await self2.originalFetch.call(window, input, init);
|
|
11546
|
+
const requestEntry = {
|
|
11547
|
+
method,
|
|
11548
|
+
url: url.slice(0, 200),
|
|
11549
|
+
// Limit URL length
|
|
11550
|
+
status: response.status,
|
|
11551
|
+
duration: Date.now() - startTime,
|
|
11552
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
11553
|
+
};
|
|
11554
|
+
if (response.status >= 400) {
|
|
11555
|
+
try {
|
|
11556
|
+
const cloned = response.clone();
|
|
11557
|
+
const body = await cloned.text();
|
|
11558
|
+
if (body) {
|
|
11559
|
+
requestEntry.responseBody = body.slice(0, MAX_RESPONSE_BODY_LENGTH);
|
|
11560
|
+
}
|
|
11561
|
+
} catch {
|
|
11562
|
+
}
|
|
11563
|
+
}
|
|
11564
|
+
self2.addNetworkRequest(requestEntry);
|
|
11565
|
+
return response;
|
|
11566
|
+
} catch (error) {
|
|
11567
|
+
self2.addNetworkRequest({
|
|
11568
|
+
method,
|
|
11569
|
+
url: url.slice(0, 200),
|
|
11570
|
+
duration: Date.now() - startTime,
|
|
11571
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11572
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
11573
|
+
});
|
|
11574
|
+
throw error;
|
|
11575
|
+
}
|
|
11576
|
+
};
|
|
11577
|
+
}
|
|
11578
|
+
captureNavigation() {
|
|
11579
|
+
if (typeof window === "undefined" || typeof history === "undefined") return;
|
|
11580
|
+
this.trackNavigation(window.location.pathname);
|
|
11581
|
+
const self2 = this;
|
|
11582
|
+
this.originalPushState = history.pushState;
|
|
11583
|
+
history.pushState = function(...args) {
|
|
11584
|
+
self2.originalPushState.apply(history, args);
|
|
11585
|
+
self2.trackNavigation(window.location.pathname);
|
|
11586
|
+
};
|
|
11587
|
+
this.originalReplaceState = history.replaceState;
|
|
11588
|
+
history.replaceState = function(...args) {
|
|
11589
|
+
self2.originalReplaceState.apply(history, args);
|
|
11590
|
+
self2.trackNavigation(window.location.pathname);
|
|
11591
|
+
};
|
|
11592
|
+
this.popstateHandler = () => {
|
|
11593
|
+
self2.trackNavigation(window.location.pathname);
|
|
11594
|
+
};
|
|
11595
|
+
window.addEventListener("popstate", this.popstateHandler);
|
|
11596
|
+
}
|
|
11597
|
+
getPerformanceMetrics() {
|
|
11598
|
+
if (typeof window === "undefined" || typeof performance === "undefined") return void 0;
|
|
11599
|
+
const metrics = {};
|
|
11600
|
+
try {
|
|
11601
|
+
const navigation = performance.getEntriesByType("navigation")[0];
|
|
11602
|
+
if (navigation) {
|
|
11603
|
+
metrics.pageLoadTime = Math.round(navigation.loadEventEnd - navigation.startTime);
|
|
11604
|
+
}
|
|
11605
|
+
} catch {
|
|
11606
|
+
}
|
|
11607
|
+
try {
|
|
11608
|
+
const memory = performance.memory;
|
|
11609
|
+
if (memory) {
|
|
11610
|
+
metrics.memoryUsage = Math.round(memory.usedJSHeapSize / 1024 / 1024);
|
|
11611
|
+
}
|
|
11612
|
+
} catch {
|
|
11613
|
+
}
|
|
11614
|
+
return Object.keys(metrics).length > 0 ? metrics : void 0;
|
|
11615
|
+
}
|
|
11616
|
+
getEnvironmentInfo() {
|
|
11617
|
+
if (typeof window === "undefined" || typeof navigator === "undefined") return void 0;
|
|
11618
|
+
return {
|
|
11619
|
+
language: navigator.language,
|
|
11620
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
11621
|
+
cookiesEnabled: navigator.cookieEnabled,
|
|
11622
|
+
localStorage: typeof localStorage !== "undefined",
|
|
11623
|
+
online: navigator.onLine
|
|
11624
|
+
};
|
|
11625
|
+
}
|
|
11626
|
+
};
|
|
11627
|
+
var contextCapture = new ContextCaptureManager();
|
|
11395
11628
|
var DEFAULT_SUPABASE_URL = "https://kyxgzjnqgvapvlnvqawz.supabase.co";
|
|
11396
11629
|
var getEnvVar = (key) => {
|
|
11397
11630
|
try {
|
|
@@ -11413,22 +11646,40 @@ var BugBearClient = class {
|
|
|
11413
11646
|
);
|
|
11414
11647
|
}
|
|
11415
11648
|
/**
|
|
11416
|
-
* Track navigation for context
|
|
11649
|
+
* Track navigation for context.
|
|
11650
|
+
* Also forwards to contextCapture for auto-tracked navigation.
|
|
11417
11651
|
*/
|
|
11418
11652
|
trackNavigation(route) {
|
|
11419
11653
|
this.navigationHistory.push(route);
|
|
11420
11654
|
if (this.navigationHistory.length > 10) {
|
|
11421
11655
|
this.navigationHistory.shift();
|
|
11422
11656
|
}
|
|
11657
|
+
contextCapture.trackNavigation(route);
|
|
11423
11658
|
}
|
|
11424
11659
|
/**
|
|
11425
|
-
* Get current navigation history
|
|
11660
|
+
* Get current navigation history.
|
|
11661
|
+
* Priority: config callback > manual tracking > auto-captured (pushState/popstate)
|
|
11426
11662
|
*/
|
|
11427
11663
|
getNavigationHistory() {
|
|
11428
11664
|
if (this.config.getNavigationHistory) {
|
|
11429
11665
|
return this.config.getNavigationHistory();
|
|
11430
11666
|
}
|
|
11431
|
-
|
|
11667
|
+
if (this.navigationHistory.length > 0) {
|
|
11668
|
+
return [...this.navigationHistory];
|
|
11669
|
+
}
|
|
11670
|
+
return contextCapture.getNavigationHistory();
|
|
11671
|
+
}
|
|
11672
|
+
/**
|
|
11673
|
+
* Get current app context.
|
|
11674
|
+
* Uses config.getAppContext() callback if provided, otherwise builds from available data.
|
|
11675
|
+
*/
|
|
11676
|
+
getAppContext() {
|
|
11677
|
+
if (this.config.getAppContext) {
|
|
11678
|
+
return this.config.getAppContext();
|
|
11679
|
+
}
|
|
11680
|
+
return {
|
|
11681
|
+
currentRoute: contextCapture.getCurrentRoute()
|
|
11682
|
+
};
|
|
11432
11683
|
}
|
|
11433
11684
|
/**
|
|
11434
11685
|
* Get current user info from host app or BugBear's own auth
|
|
@@ -11468,6 +11719,8 @@ var BugBearClient = class {
|
|
|
11468
11719
|
project_id: this.config.projectId,
|
|
11469
11720
|
reporter_id: userInfo.id,
|
|
11470
11721
|
// User ID from host app (required)
|
|
11722
|
+
reporter_name: testerInfo?.name || userInfo.name || null,
|
|
11723
|
+
reporter_email: userInfo.email || null,
|
|
11471
11724
|
tester_id: testerInfo?.id || null,
|
|
11472
11725
|
// Tester record ID (optional)
|
|
11473
11726
|
report_type: report.type,
|
|
@@ -11481,6 +11734,7 @@ var BugBearClient = class {
|
|
|
11481
11734
|
app_context: report.appContext,
|
|
11482
11735
|
device_info: report.deviceInfo || this.getDeviceInfo(),
|
|
11483
11736
|
navigation_history: this.getNavigationHistory(),
|
|
11737
|
+
enhanced_context: report.enhancedContext || contextCapture.getEnhancedContext(),
|
|
11484
11738
|
assignment_id: report.assignmentId,
|
|
11485
11739
|
test_case_id: report.testCaseId
|
|
11486
11740
|
};
|
|
@@ -12714,163 +12968,6 @@ var BugBearClient = class {
|
|
|
12714
12968
|
function createBugBear(config) {
|
|
12715
12969
|
return new BugBearClient(config);
|
|
12716
12970
|
}
|
|
12717
|
-
var MAX_CONSOLE_LOGS = 50;
|
|
12718
|
-
var MAX_NETWORK_REQUESTS = 20;
|
|
12719
|
-
var ContextCaptureManager = class {
|
|
12720
|
-
constructor() {
|
|
12721
|
-
this.consoleLogs = [];
|
|
12722
|
-
this.networkRequests = [];
|
|
12723
|
-
this.originalConsole = {};
|
|
12724
|
-
this.isCapturing = false;
|
|
12725
|
-
}
|
|
12726
|
-
/**
|
|
12727
|
-
* Start capturing console logs and network requests
|
|
12728
|
-
*/
|
|
12729
|
-
startCapture() {
|
|
12730
|
-
if (this.isCapturing) return;
|
|
12731
|
-
this.isCapturing = true;
|
|
12732
|
-
this.captureConsole();
|
|
12733
|
-
this.captureFetch();
|
|
12734
|
-
}
|
|
12735
|
-
/**
|
|
12736
|
-
* Stop capturing and restore original functions
|
|
12737
|
-
*/
|
|
12738
|
-
stopCapture() {
|
|
12739
|
-
if (!this.isCapturing) return;
|
|
12740
|
-
this.isCapturing = false;
|
|
12741
|
-
if (this.originalConsole.log) console.log = this.originalConsole.log;
|
|
12742
|
-
if (this.originalConsole.warn) console.warn = this.originalConsole.warn;
|
|
12743
|
-
if (this.originalConsole.error) console.error = this.originalConsole.error;
|
|
12744
|
-
if (this.originalConsole.info) console.info = this.originalConsole.info;
|
|
12745
|
-
if (this.originalFetch && typeof window !== "undefined") {
|
|
12746
|
-
window.fetch = this.originalFetch;
|
|
12747
|
-
}
|
|
12748
|
-
}
|
|
12749
|
-
/**
|
|
12750
|
-
* Get captured context for a bug report
|
|
12751
|
-
*/
|
|
12752
|
-
getEnhancedContext() {
|
|
12753
|
-
return {
|
|
12754
|
-
consoleLogs: [...this.consoleLogs],
|
|
12755
|
-
networkRequests: [...this.networkRequests],
|
|
12756
|
-
performanceMetrics: this.getPerformanceMetrics(),
|
|
12757
|
-
environment: this.getEnvironmentInfo()
|
|
12758
|
-
};
|
|
12759
|
-
}
|
|
12760
|
-
/**
|
|
12761
|
-
* Clear captured data
|
|
12762
|
-
*/
|
|
12763
|
-
clear() {
|
|
12764
|
-
this.consoleLogs = [];
|
|
12765
|
-
this.networkRequests = [];
|
|
12766
|
-
}
|
|
12767
|
-
/**
|
|
12768
|
-
* Add a log entry manually (for custom logging)
|
|
12769
|
-
*/
|
|
12770
|
-
addLog(level, message, args) {
|
|
12771
|
-
this.consoleLogs.push({
|
|
12772
|
-
level,
|
|
12773
|
-
message,
|
|
12774
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12775
|
-
args
|
|
12776
|
-
});
|
|
12777
|
-
if (this.consoleLogs.length > MAX_CONSOLE_LOGS) {
|
|
12778
|
-
this.consoleLogs = this.consoleLogs.slice(-MAX_CONSOLE_LOGS);
|
|
12779
|
-
}
|
|
12780
|
-
}
|
|
12781
|
-
/**
|
|
12782
|
-
* Add a network request manually
|
|
12783
|
-
*/
|
|
12784
|
-
addNetworkRequest(request) {
|
|
12785
|
-
this.networkRequests.push(request);
|
|
12786
|
-
if (this.networkRequests.length > MAX_NETWORK_REQUESTS) {
|
|
12787
|
-
this.networkRequests = this.networkRequests.slice(-MAX_NETWORK_REQUESTS);
|
|
12788
|
-
}
|
|
12789
|
-
}
|
|
12790
|
-
captureConsole() {
|
|
12791
|
-
if (typeof console === "undefined") return;
|
|
12792
|
-
const levels = ["log", "warn", "error", "info"];
|
|
12793
|
-
levels.forEach((level) => {
|
|
12794
|
-
this.originalConsole[level] = console[level];
|
|
12795
|
-
console[level] = (...args) => {
|
|
12796
|
-
this.originalConsole[level]?.apply(console, args);
|
|
12797
|
-
try {
|
|
12798
|
-
const message = args.map((arg) => {
|
|
12799
|
-
if (typeof arg === "string") return arg;
|
|
12800
|
-
try {
|
|
12801
|
-
return JSON.stringify(arg);
|
|
12802
|
-
} catch {
|
|
12803
|
-
return String(arg);
|
|
12804
|
-
}
|
|
12805
|
-
}).join(" ");
|
|
12806
|
-
this.addLog(level, message.slice(0, 500));
|
|
12807
|
-
} catch {
|
|
12808
|
-
}
|
|
12809
|
-
};
|
|
12810
|
-
});
|
|
12811
|
-
}
|
|
12812
|
-
captureFetch() {
|
|
12813
|
-
if (typeof window === "undefined" || typeof fetch === "undefined") return;
|
|
12814
|
-
this.originalFetch = window.fetch;
|
|
12815
|
-
const self2 = this;
|
|
12816
|
-
window.fetch = async function(input, init) {
|
|
12817
|
-
const startTime = Date.now();
|
|
12818
|
-
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
12819
|
-
const method = init?.method || "GET";
|
|
12820
|
-
try {
|
|
12821
|
-
const response = await self2.originalFetch.call(window, input, init);
|
|
12822
|
-
self2.addNetworkRequest({
|
|
12823
|
-
method,
|
|
12824
|
-
url: url.slice(0, 200),
|
|
12825
|
-
// Limit URL length
|
|
12826
|
-
status: response.status,
|
|
12827
|
-
duration: Date.now() - startTime,
|
|
12828
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
12829
|
-
});
|
|
12830
|
-
return response;
|
|
12831
|
-
} catch (error) {
|
|
12832
|
-
self2.addNetworkRequest({
|
|
12833
|
-
method,
|
|
12834
|
-
url: url.slice(0, 200),
|
|
12835
|
-
duration: Date.now() - startTime,
|
|
12836
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12837
|
-
error: error instanceof Error ? error.message : "Unknown error"
|
|
12838
|
-
});
|
|
12839
|
-
throw error;
|
|
12840
|
-
}
|
|
12841
|
-
};
|
|
12842
|
-
}
|
|
12843
|
-
getPerformanceMetrics() {
|
|
12844
|
-
if (typeof window === "undefined" || typeof performance === "undefined") return void 0;
|
|
12845
|
-
const metrics = {};
|
|
12846
|
-
try {
|
|
12847
|
-
const navigation = performance.getEntriesByType("navigation")[0];
|
|
12848
|
-
if (navigation) {
|
|
12849
|
-
metrics.pageLoadTime = Math.round(navigation.loadEventEnd - navigation.startTime);
|
|
12850
|
-
}
|
|
12851
|
-
} catch {
|
|
12852
|
-
}
|
|
12853
|
-
try {
|
|
12854
|
-
const memory = performance.memory;
|
|
12855
|
-
if (memory) {
|
|
12856
|
-
metrics.memoryUsage = Math.round(memory.usedJSHeapSize / 1024 / 1024);
|
|
12857
|
-
}
|
|
12858
|
-
} catch {
|
|
12859
|
-
}
|
|
12860
|
-
return Object.keys(metrics).length > 0 ? metrics : void 0;
|
|
12861
|
-
}
|
|
12862
|
-
getEnvironmentInfo() {
|
|
12863
|
-
if (typeof window === "undefined" || typeof navigator === "undefined") return void 0;
|
|
12864
|
-
return {
|
|
12865
|
-
language: navigator.language,
|
|
12866
|
-
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
12867
|
-
cookiesEnabled: navigator.cookieEnabled,
|
|
12868
|
-
localStorage: typeof localStorage !== "undefined",
|
|
12869
|
-
online: navigator.onLine
|
|
12870
|
-
};
|
|
12871
|
-
}
|
|
12872
|
-
};
|
|
12873
|
-
var contextCapture = new ContextCaptureManager();
|
|
12874
12971
|
|
|
12875
12972
|
// src/BugBearProvider.tsx
|
|
12876
12973
|
var import_react_native = require("react-native");
|
|
@@ -13071,6 +13168,7 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
13071
13168
|
(0, import_react.useEffect)(() => {
|
|
13072
13169
|
if (enabled && !hasInitialized.current) {
|
|
13073
13170
|
hasInitialized.current = true;
|
|
13171
|
+
contextCapture.startCapture();
|
|
13074
13172
|
const newClient = createBugBear(config);
|
|
13075
13173
|
setClient(newClient);
|
|
13076
13174
|
initializeBugBear(newClient);
|
|
@@ -14296,12 +14394,18 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14296
14394
|
const [reportType, setReportType] = (0, import_react10.useState)(prefill?.type || "bug");
|
|
14297
14395
|
const [severity, setSeverity] = (0, import_react10.useState)("medium");
|
|
14298
14396
|
const [description, setDescription] = (0, import_react10.useState)("");
|
|
14397
|
+
const [affectedScreen, setAffectedScreen] = (0, import_react10.useState)("");
|
|
14299
14398
|
const [submitting, setSubmitting] = (0, import_react10.useState)(false);
|
|
14300
14399
|
const images = useImageAttachments(uploadImage, 5, "screenshots");
|
|
14301
14400
|
const isBugType = reportType === "bug" || reportType === "test_fail";
|
|
14302
14401
|
const handleSubmit = async () => {
|
|
14303
14402
|
if (!client || !description.trim()) return;
|
|
14304
14403
|
setSubmitting(true);
|
|
14404
|
+
const baseContext = client.getAppContext();
|
|
14405
|
+
const appContext = {
|
|
14406
|
+
...baseContext,
|
|
14407
|
+
currentRoute: affectedScreen.trim() || baseContext.currentRoute
|
|
14408
|
+
};
|
|
14305
14409
|
const screenshotUrls = images.getScreenshotUrls();
|
|
14306
14410
|
await client.submitReport({
|
|
14307
14411
|
type: reportType,
|
|
@@ -14309,7 +14413,7 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14309
14413
|
severity: isBugType ? severity : void 0,
|
|
14310
14414
|
assignmentId: prefill?.assignmentId,
|
|
14311
14415
|
testCaseId: prefill?.testCaseId,
|
|
14312
|
-
appContext
|
|
14416
|
+
appContext,
|
|
14313
14417
|
deviceInfo: getDeviceInfo(),
|
|
14314
14418
|
screenshots: screenshotUrls.length > 0 ? screenshotUrls : void 0
|
|
14315
14419
|
});
|
|
@@ -14357,7 +14461,16 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14357
14461
|
numberOfLines: 4,
|
|
14358
14462
|
textAlignVertical: "top"
|
|
14359
14463
|
}
|
|
14360
|
-
)), /* @__PURE__ */ import_react10.default.createElement(
|
|
14464
|
+
)), isBugType && /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, { style: styles7.section }, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: shared.label }, "Which screen?"), /* @__PURE__ */ import_react10.default.createElement(
|
|
14465
|
+
import_react_native9.TextInput,
|
|
14466
|
+
{
|
|
14467
|
+
style: styles7.screenInput,
|
|
14468
|
+
value: affectedScreen,
|
|
14469
|
+
onChangeText: setAffectedScreen,
|
|
14470
|
+
placeholder: "e.g. Reservations, Settings...",
|
|
14471
|
+
placeholderTextColor: colors.textMuted
|
|
14472
|
+
}
|
|
14473
|
+
), /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: styles7.screenHint }, "Which screen or area was the bug on? (optional)")), /* @__PURE__ */ import_react10.default.createElement(
|
|
14361
14474
|
ImagePickerButtons,
|
|
14362
14475
|
{
|
|
14363
14476
|
images: images.images,
|
|
@@ -14388,7 +14501,9 @@ var styles7 = import_react_native9.StyleSheet.create({
|
|
|
14388
14501
|
severityRow: { flexDirection: "row", gap: 8 },
|
|
14389
14502
|
sevButton: { flex: 1, paddingVertical: 8, borderRadius: 8, alignItems: "center", borderWidth: 1, borderColor: colors.border, backgroundColor: colors.card },
|
|
14390
14503
|
sevText: { fontSize: 12, fontWeight: "500", color: colors.textSecondary, textTransform: "capitalize" },
|
|
14391
|
-
descInput: { backgroundColor: colors.card, borderWidth: 1, borderColor: colors.border, borderRadius: 12, paddingHorizontal: 14, paddingVertical: 12, fontSize: 14, color: colors.textPrimary, minHeight: 100 }
|
|
14504
|
+
descInput: { backgroundColor: colors.card, borderWidth: 1, borderColor: colors.border, borderRadius: 12, paddingHorizontal: 14, paddingVertical: 12, fontSize: 14, color: colors.textPrimary, minHeight: 100 },
|
|
14505
|
+
screenInput: { backgroundColor: colors.card, borderWidth: 1, borderColor: colors.border, borderRadius: 8, paddingHorizontal: 12, paddingVertical: 8, fontSize: 13, color: colors.textPrimary },
|
|
14506
|
+
screenHint: { fontSize: 11, color: colors.textMuted, marginTop: 4 }
|
|
14392
14507
|
});
|
|
14393
14508
|
|
|
14394
14509
|
// src/widget/screens/ReportSuccessScreen.tsx
|
package/dist/index.mjs
CHANGED
|
@@ -11361,6 +11361,239 @@ function shouldShowDeprecationWarning() {
|
|
|
11361
11361
|
if (shouldShowDeprecationWarning()) console.warn("\u26A0\uFE0F Node.js 18 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 20 or later. For more information, visit: https://github.com/orgs/supabase/discussions/37217");
|
|
11362
11362
|
|
|
11363
11363
|
// ../core/dist/index.mjs
|
|
11364
|
+
var MAX_CONSOLE_LOGS = 50;
|
|
11365
|
+
var MAX_NETWORK_REQUESTS = 20;
|
|
11366
|
+
var MAX_NAVIGATION_HISTORY = 20;
|
|
11367
|
+
var MAX_RESPONSE_BODY_LENGTH = 500;
|
|
11368
|
+
var ContextCaptureManager = class {
|
|
11369
|
+
constructor() {
|
|
11370
|
+
this.consoleLogs = [];
|
|
11371
|
+
this.networkRequests = [];
|
|
11372
|
+
this.navigationHistory = [];
|
|
11373
|
+
this.originalConsole = {};
|
|
11374
|
+
this.isCapturing = false;
|
|
11375
|
+
}
|
|
11376
|
+
/**
|
|
11377
|
+
* Start capturing console logs, network requests, and navigation
|
|
11378
|
+
*/
|
|
11379
|
+
startCapture() {
|
|
11380
|
+
if (this.isCapturing) return;
|
|
11381
|
+
this.isCapturing = true;
|
|
11382
|
+
this.captureConsole();
|
|
11383
|
+
this.captureFetch();
|
|
11384
|
+
this.captureNavigation();
|
|
11385
|
+
}
|
|
11386
|
+
/**
|
|
11387
|
+
* Stop capturing and restore original functions
|
|
11388
|
+
*/
|
|
11389
|
+
stopCapture() {
|
|
11390
|
+
if (!this.isCapturing) return;
|
|
11391
|
+
this.isCapturing = false;
|
|
11392
|
+
if (this.originalConsole.log) console.log = this.originalConsole.log;
|
|
11393
|
+
if (this.originalConsole.warn) console.warn = this.originalConsole.warn;
|
|
11394
|
+
if (this.originalConsole.error) console.error = this.originalConsole.error;
|
|
11395
|
+
if (this.originalConsole.info) console.info = this.originalConsole.info;
|
|
11396
|
+
if (this.originalFetch && typeof window !== "undefined") {
|
|
11397
|
+
window.fetch = this.originalFetch;
|
|
11398
|
+
}
|
|
11399
|
+
if (typeof window !== "undefined" && typeof history !== "undefined") {
|
|
11400
|
+
if (this.originalPushState) {
|
|
11401
|
+
history.pushState = this.originalPushState;
|
|
11402
|
+
}
|
|
11403
|
+
if (this.originalReplaceState) {
|
|
11404
|
+
history.replaceState = this.originalReplaceState;
|
|
11405
|
+
}
|
|
11406
|
+
if (this.popstateHandler) {
|
|
11407
|
+
window.removeEventListener("popstate", this.popstateHandler);
|
|
11408
|
+
}
|
|
11409
|
+
}
|
|
11410
|
+
}
|
|
11411
|
+
/**
|
|
11412
|
+
* Get captured context for a bug report
|
|
11413
|
+
*/
|
|
11414
|
+
getEnhancedContext() {
|
|
11415
|
+
return {
|
|
11416
|
+
consoleLogs: [...this.consoleLogs],
|
|
11417
|
+
networkRequests: [...this.networkRequests],
|
|
11418
|
+
navigationHistory: [...this.navigationHistory],
|
|
11419
|
+
performanceMetrics: this.getPerformanceMetrics(),
|
|
11420
|
+
environment: this.getEnvironmentInfo()
|
|
11421
|
+
};
|
|
11422
|
+
}
|
|
11423
|
+
/**
|
|
11424
|
+
* Get the auto-captured navigation history
|
|
11425
|
+
*/
|
|
11426
|
+
getNavigationHistory() {
|
|
11427
|
+
return [...this.navigationHistory];
|
|
11428
|
+
}
|
|
11429
|
+
/**
|
|
11430
|
+
* Get the current route (last entry in navigation history, or window.location)
|
|
11431
|
+
*/
|
|
11432
|
+
getCurrentRoute() {
|
|
11433
|
+
if (this.navigationHistory.length > 0) {
|
|
11434
|
+
return this.navigationHistory[this.navigationHistory.length - 1];
|
|
11435
|
+
}
|
|
11436
|
+
if (typeof window !== "undefined") {
|
|
11437
|
+
return window.location.pathname;
|
|
11438
|
+
}
|
|
11439
|
+
return "unknown";
|
|
11440
|
+
}
|
|
11441
|
+
/**
|
|
11442
|
+
* Manually track a navigation event (for React Native or custom routing)
|
|
11443
|
+
*/
|
|
11444
|
+
trackNavigation(route) {
|
|
11445
|
+
const last = this.navigationHistory[this.navigationHistory.length - 1];
|
|
11446
|
+
if (route === last) return;
|
|
11447
|
+
this.navigationHistory.push(route);
|
|
11448
|
+
if (this.navigationHistory.length > MAX_NAVIGATION_HISTORY) {
|
|
11449
|
+
this.navigationHistory.shift();
|
|
11450
|
+
}
|
|
11451
|
+
}
|
|
11452
|
+
/**
|
|
11453
|
+
* Clear captured data
|
|
11454
|
+
*/
|
|
11455
|
+
clear() {
|
|
11456
|
+
this.consoleLogs = [];
|
|
11457
|
+
this.networkRequests = [];
|
|
11458
|
+
this.navigationHistory = [];
|
|
11459
|
+
}
|
|
11460
|
+
/**
|
|
11461
|
+
* Add a log entry manually (for custom logging)
|
|
11462
|
+
*/
|
|
11463
|
+
addLog(level, message, args) {
|
|
11464
|
+
this.consoleLogs.push({
|
|
11465
|
+
level,
|
|
11466
|
+
message,
|
|
11467
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11468
|
+
args
|
|
11469
|
+
});
|
|
11470
|
+
if (this.consoleLogs.length > MAX_CONSOLE_LOGS) {
|
|
11471
|
+
this.consoleLogs = this.consoleLogs.slice(-MAX_CONSOLE_LOGS);
|
|
11472
|
+
}
|
|
11473
|
+
}
|
|
11474
|
+
/**
|
|
11475
|
+
* Add a network request manually
|
|
11476
|
+
*/
|
|
11477
|
+
addNetworkRequest(request) {
|
|
11478
|
+
this.networkRequests.push(request);
|
|
11479
|
+
if (this.networkRequests.length > MAX_NETWORK_REQUESTS) {
|
|
11480
|
+
this.networkRequests = this.networkRequests.slice(-MAX_NETWORK_REQUESTS);
|
|
11481
|
+
}
|
|
11482
|
+
}
|
|
11483
|
+
captureConsole() {
|
|
11484
|
+
if (typeof console === "undefined") return;
|
|
11485
|
+
const levels = ["log", "warn", "error", "info"];
|
|
11486
|
+
levels.forEach((level) => {
|
|
11487
|
+
this.originalConsole[level] = console[level];
|
|
11488
|
+
console[level] = (...args) => {
|
|
11489
|
+
this.originalConsole[level]?.apply(console, args);
|
|
11490
|
+
try {
|
|
11491
|
+
const message = args.map((arg) => {
|
|
11492
|
+
if (typeof arg === "string") return arg;
|
|
11493
|
+
try {
|
|
11494
|
+
return JSON.stringify(arg);
|
|
11495
|
+
} catch {
|
|
11496
|
+
return String(arg);
|
|
11497
|
+
}
|
|
11498
|
+
}).join(" ");
|
|
11499
|
+
this.addLog(level, message.slice(0, 500));
|
|
11500
|
+
} catch {
|
|
11501
|
+
}
|
|
11502
|
+
};
|
|
11503
|
+
});
|
|
11504
|
+
}
|
|
11505
|
+
captureFetch() {
|
|
11506
|
+
if (typeof window === "undefined" || typeof fetch === "undefined") return;
|
|
11507
|
+
this.originalFetch = window.fetch;
|
|
11508
|
+
const self2 = this;
|
|
11509
|
+
window.fetch = async function(input, init) {
|
|
11510
|
+
const startTime = Date.now();
|
|
11511
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
11512
|
+
const method = init?.method || "GET";
|
|
11513
|
+
try {
|
|
11514
|
+
const response = await self2.originalFetch.call(window, input, init);
|
|
11515
|
+
const requestEntry = {
|
|
11516
|
+
method,
|
|
11517
|
+
url: url.slice(0, 200),
|
|
11518
|
+
// Limit URL length
|
|
11519
|
+
status: response.status,
|
|
11520
|
+
duration: Date.now() - startTime,
|
|
11521
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
11522
|
+
};
|
|
11523
|
+
if (response.status >= 400) {
|
|
11524
|
+
try {
|
|
11525
|
+
const cloned = response.clone();
|
|
11526
|
+
const body = await cloned.text();
|
|
11527
|
+
if (body) {
|
|
11528
|
+
requestEntry.responseBody = body.slice(0, MAX_RESPONSE_BODY_LENGTH);
|
|
11529
|
+
}
|
|
11530
|
+
} catch {
|
|
11531
|
+
}
|
|
11532
|
+
}
|
|
11533
|
+
self2.addNetworkRequest(requestEntry);
|
|
11534
|
+
return response;
|
|
11535
|
+
} catch (error) {
|
|
11536
|
+
self2.addNetworkRequest({
|
|
11537
|
+
method,
|
|
11538
|
+
url: url.slice(0, 200),
|
|
11539
|
+
duration: Date.now() - startTime,
|
|
11540
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11541
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
11542
|
+
});
|
|
11543
|
+
throw error;
|
|
11544
|
+
}
|
|
11545
|
+
};
|
|
11546
|
+
}
|
|
11547
|
+
captureNavigation() {
|
|
11548
|
+
if (typeof window === "undefined" || typeof history === "undefined") return;
|
|
11549
|
+
this.trackNavigation(window.location.pathname);
|
|
11550
|
+
const self2 = this;
|
|
11551
|
+
this.originalPushState = history.pushState;
|
|
11552
|
+
history.pushState = function(...args) {
|
|
11553
|
+
self2.originalPushState.apply(history, args);
|
|
11554
|
+
self2.trackNavigation(window.location.pathname);
|
|
11555
|
+
};
|
|
11556
|
+
this.originalReplaceState = history.replaceState;
|
|
11557
|
+
history.replaceState = function(...args) {
|
|
11558
|
+
self2.originalReplaceState.apply(history, args);
|
|
11559
|
+
self2.trackNavigation(window.location.pathname);
|
|
11560
|
+
};
|
|
11561
|
+
this.popstateHandler = () => {
|
|
11562
|
+
self2.trackNavigation(window.location.pathname);
|
|
11563
|
+
};
|
|
11564
|
+
window.addEventListener("popstate", this.popstateHandler);
|
|
11565
|
+
}
|
|
11566
|
+
getPerformanceMetrics() {
|
|
11567
|
+
if (typeof window === "undefined" || typeof performance === "undefined") return void 0;
|
|
11568
|
+
const metrics = {};
|
|
11569
|
+
try {
|
|
11570
|
+
const navigation = performance.getEntriesByType("navigation")[0];
|
|
11571
|
+
if (navigation) {
|
|
11572
|
+
metrics.pageLoadTime = Math.round(navigation.loadEventEnd - navigation.startTime);
|
|
11573
|
+
}
|
|
11574
|
+
} catch {
|
|
11575
|
+
}
|
|
11576
|
+
try {
|
|
11577
|
+
const memory = performance.memory;
|
|
11578
|
+
if (memory) {
|
|
11579
|
+
metrics.memoryUsage = Math.round(memory.usedJSHeapSize / 1024 / 1024);
|
|
11580
|
+
}
|
|
11581
|
+
} catch {
|
|
11582
|
+
}
|
|
11583
|
+
return Object.keys(metrics).length > 0 ? metrics : void 0;
|
|
11584
|
+
}
|
|
11585
|
+
getEnvironmentInfo() {
|
|
11586
|
+
if (typeof window === "undefined" || typeof navigator === "undefined") return void 0;
|
|
11587
|
+
return {
|
|
11588
|
+
language: navigator.language,
|
|
11589
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
11590
|
+
cookiesEnabled: navigator.cookieEnabled,
|
|
11591
|
+
localStorage: typeof localStorage !== "undefined",
|
|
11592
|
+
online: navigator.onLine
|
|
11593
|
+
};
|
|
11594
|
+
}
|
|
11595
|
+
};
|
|
11596
|
+
var contextCapture = new ContextCaptureManager();
|
|
11364
11597
|
var DEFAULT_SUPABASE_URL = "https://kyxgzjnqgvapvlnvqawz.supabase.co";
|
|
11365
11598
|
var getEnvVar = (key) => {
|
|
11366
11599
|
try {
|
|
@@ -11382,22 +11615,40 @@ var BugBearClient = class {
|
|
|
11382
11615
|
);
|
|
11383
11616
|
}
|
|
11384
11617
|
/**
|
|
11385
|
-
* Track navigation for context
|
|
11618
|
+
* Track navigation for context.
|
|
11619
|
+
* Also forwards to contextCapture for auto-tracked navigation.
|
|
11386
11620
|
*/
|
|
11387
11621
|
trackNavigation(route) {
|
|
11388
11622
|
this.navigationHistory.push(route);
|
|
11389
11623
|
if (this.navigationHistory.length > 10) {
|
|
11390
11624
|
this.navigationHistory.shift();
|
|
11391
11625
|
}
|
|
11626
|
+
contextCapture.trackNavigation(route);
|
|
11392
11627
|
}
|
|
11393
11628
|
/**
|
|
11394
|
-
* Get current navigation history
|
|
11629
|
+
* Get current navigation history.
|
|
11630
|
+
* Priority: config callback > manual tracking > auto-captured (pushState/popstate)
|
|
11395
11631
|
*/
|
|
11396
11632
|
getNavigationHistory() {
|
|
11397
11633
|
if (this.config.getNavigationHistory) {
|
|
11398
11634
|
return this.config.getNavigationHistory();
|
|
11399
11635
|
}
|
|
11400
|
-
|
|
11636
|
+
if (this.navigationHistory.length > 0) {
|
|
11637
|
+
return [...this.navigationHistory];
|
|
11638
|
+
}
|
|
11639
|
+
return contextCapture.getNavigationHistory();
|
|
11640
|
+
}
|
|
11641
|
+
/**
|
|
11642
|
+
* Get current app context.
|
|
11643
|
+
* Uses config.getAppContext() callback if provided, otherwise builds from available data.
|
|
11644
|
+
*/
|
|
11645
|
+
getAppContext() {
|
|
11646
|
+
if (this.config.getAppContext) {
|
|
11647
|
+
return this.config.getAppContext();
|
|
11648
|
+
}
|
|
11649
|
+
return {
|
|
11650
|
+
currentRoute: contextCapture.getCurrentRoute()
|
|
11651
|
+
};
|
|
11401
11652
|
}
|
|
11402
11653
|
/**
|
|
11403
11654
|
* Get current user info from host app or BugBear's own auth
|
|
@@ -11437,6 +11688,8 @@ var BugBearClient = class {
|
|
|
11437
11688
|
project_id: this.config.projectId,
|
|
11438
11689
|
reporter_id: userInfo.id,
|
|
11439
11690
|
// User ID from host app (required)
|
|
11691
|
+
reporter_name: testerInfo?.name || userInfo.name || null,
|
|
11692
|
+
reporter_email: userInfo.email || null,
|
|
11440
11693
|
tester_id: testerInfo?.id || null,
|
|
11441
11694
|
// Tester record ID (optional)
|
|
11442
11695
|
report_type: report.type,
|
|
@@ -11450,6 +11703,7 @@ var BugBearClient = class {
|
|
|
11450
11703
|
app_context: report.appContext,
|
|
11451
11704
|
device_info: report.deviceInfo || this.getDeviceInfo(),
|
|
11452
11705
|
navigation_history: this.getNavigationHistory(),
|
|
11706
|
+
enhanced_context: report.enhancedContext || contextCapture.getEnhancedContext(),
|
|
11453
11707
|
assignment_id: report.assignmentId,
|
|
11454
11708
|
test_case_id: report.testCaseId
|
|
11455
11709
|
};
|
|
@@ -12683,163 +12937,6 @@ var BugBearClient = class {
|
|
|
12683
12937
|
function createBugBear(config) {
|
|
12684
12938
|
return new BugBearClient(config);
|
|
12685
12939
|
}
|
|
12686
|
-
var MAX_CONSOLE_LOGS = 50;
|
|
12687
|
-
var MAX_NETWORK_REQUESTS = 20;
|
|
12688
|
-
var ContextCaptureManager = class {
|
|
12689
|
-
constructor() {
|
|
12690
|
-
this.consoleLogs = [];
|
|
12691
|
-
this.networkRequests = [];
|
|
12692
|
-
this.originalConsole = {};
|
|
12693
|
-
this.isCapturing = false;
|
|
12694
|
-
}
|
|
12695
|
-
/**
|
|
12696
|
-
* Start capturing console logs and network requests
|
|
12697
|
-
*/
|
|
12698
|
-
startCapture() {
|
|
12699
|
-
if (this.isCapturing) return;
|
|
12700
|
-
this.isCapturing = true;
|
|
12701
|
-
this.captureConsole();
|
|
12702
|
-
this.captureFetch();
|
|
12703
|
-
}
|
|
12704
|
-
/**
|
|
12705
|
-
* Stop capturing and restore original functions
|
|
12706
|
-
*/
|
|
12707
|
-
stopCapture() {
|
|
12708
|
-
if (!this.isCapturing) return;
|
|
12709
|
-
this.isCapturing = false;
|
|
12710
|
-
if (this.originalConsole.log) console.log = this.originalConsole.log;
|
|
12711
|
-
if (this.originalConsole.warn) console.warn = this.originalConsole.warn;
|
|
12712
|
-
if (this.originalConsole.error) console.error = this.originalConsole.error;
|
|
12713
|
-
if (this.originalConsole.info) console.info = this.originalConsole.info;
|
|
12714
|
-
if (this.originalFetch && typeof window !== "undefined") {
|
|
12715
|
-
window.fetch = this.originalFetch;
|
|
12716
|
-
}
|
|
12717
|
-
}
|
|
12718
|
-
/**
|
|
12719
|
-
* Get captured context for a bug report
|
|
12720
|
-
*/
|
|
12721
|
-
getEnhancedContext() {
|
|
12722
|
-
return {
|
|
12723
|
-
consoleLogs: [...this.consoleLogs],
|
|
12724
|
-
networkRequests: [...this.networkRequests],
|
|
12725
|
-
performanceMetrics: this.getPerformanceMetrics(),
|
|
12726
|
-
environment: this.getEnvironmentInfo()
|
|
12727
|
-
};
|
|
12728
|
-
}
|
|
12729
|
-
/**
|
|
12730
|
-
* Clear captured data
|
|
12731
|
-
*/
|
|
12732
|
-
clear() {
|
|
12733
|
-
this.consoleLogs = [];
|
|
12734
|
-
this.networkRequests = [];
|
|
12735
|
-
}
|
|
12736
|
-
/**
|
|
12737
|
-
* Add a log entry manually (for custom logging)
|
|
12738
|
-
*/
|
|
12739
|
-
addLog(level, message, args) {
|
|
12740
|
-
this.consoleLogs.push({
|
|
12741
|
-
level,
|
|
12742
|
-
message,
|
|
12743
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12744
|
-
args
|
|
12745
|
-
});
|
|
12746
|
-
if (this.consoleLogs.length > MAX_CONSOLE_LOGS) {
|
|
12747
|
-
this.consoleLogs = this.consoleLogs.slice(-MAX_CONSOLE_LOGS);
|
|
12748
|
-
}
|
|
12749
|
-
}
|
|
12750
|
-
/**
|
|
12751
|
-
* Add a network request manually
|
|
12752
|
-
*/
|
|
12753
|
-
addNetworkRequest(request) {
|
|
12754
|
-
this.networkRequests.push(request);
|
|
12755
|
-
if (this.networkRequests.length > MAX_NETWORK_REQUESTS) {
|
|
12756
|
-
this.networkRequests = this.networkRequests.slice(-MAX_NETWORK_REQUESTS);
|
|
12757
|
-
}
|
|
12758
|
-
}
|
|
12759
|
-
captureConsole() {
|
|
12760
|
-
if (typeof console === "undefined") return;
|
|
12761
|
-
const levels = ["log", "warn", "error", "info"];
|
|
12762
|
-
levels.forEach((level) => {
|
|
12763
|
-
this.originalConsole[level] = console[level];
|
|
12764
|
-
console[level] = (...args) => {
|
|
12765
|
-
this.originalConsole[level]?.apply(console, args);
|
|
12766
|
-
try {
|
|
12767
|
-
const message = args.map((arg) => {
|
|
12768
|
-
if (typeof arg === "string") return arg;
|
|
12769
|
-
try {
|
|
12770
|
-
return JSON.stringify(arg);
|
|
12771
|
-
} catch {
|
|
12772
|
-
return String(arg);
|
|
12773
|
-
}
|
|
12774
|
-
}).join(" ");
|
|
12775
|
-
this.addLog(level, message.slice(0, 500));
|
|
12776
|
-
} catch {
|
|
12777
|
-
}
|
|
12778
|
-
};
|
|
12779
|
-
});
|
|
12780
|
-
}
|
|
12781
|
-
captureFetch() {
|
|
12782
|
-
if (typeof window === "undefined" || typeof fetch === "undefined") return;
|
|
12783
|
-
this.originalFetch = window.fetch;
|
|
12784
|
-
const self2 = this;
|
|
12785
|
-
window.fetch = async function(input, init) {
|
|
12786
|
-
const startTime = Date.now();
|
|
12787
|
-
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
12788
|
-
const method = init?.method || "GET";
|
|
12789
|
-
try {
|
|
12790
|
-
const response = await self2.originalFetch.call(window, input, init);
|
|
12791
|
-
self2.addNetworkRequest({
|
|
12792
|
-
method,
|
|
12793
|
-
url: url.slice(0, 200),
|
|
12794
|
-
// Limit URL length
|
|
12795
|
-
status: response.status,
|
|
12796
|
-
duration: Date.now() - startTime,
|
|
12797
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
12798
|
-
});
|
|
12799
|
-
return response;
|
|
12800
|
-
} catch (error) {
|
|
12801
|
-
self2.addNetworkRequest({
|
|
12802
|
-
method,
|
|
12803
|
-
url: url.slice(0, 200),
|
|
12804
|
-
duration: Date.now() - startTime,
|
|
12805
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12806
|
-
error: error instanceof Error ? error.message : "Unknown error"
|
|
12807
|
-
});
|
|
12808
|
-
throw error;
|
|
12809
|
-
}
|
|
12810
|
-
};
|
|
12811
|
-
}
|
|
12812
|
-
getPerformanceMetrics() {
|
|
12813
|
-
if (typeof window === "undefined" || typeof performance === "undefined") return void 0;
|
|
12814
|
-
const metrics = {};
|
|
12815
|
-
try {
|
|
12816
|
-
const navigation = performance.getEntriesByType("navigation")[0];
|
|
12817
|
-
if (navigation) {
|
|
12818
|
-
metrics.pageLoadTime = Math.round(navigation.loadEventEnd - navigation.startTime);
|
|
12819
|
-
}
|
|
12820
|
-
} catch {
|
|
12821
|
-
}
|
|
12822
|
-
try {
|
|
12823
|
-
const memory = performance.memory;
|
|
12824
|
-
if (memory) {
|
|
12825
|
-
metrics.memoryUsage = Math.round(memory.usedJSHeapSize / 1024 / 1024);
|
|
12826
|
-
}
|
|
12827
|
-
} catch {
|
|
12828
|
-
}
|
|
12829
|
-
return Object.keys(metrics).length > 0 ? metrics : void 0;
|
|
12830
|
-
}
|
|
12831
|
-
getEnvironmentInfo() {
|
|
12832
|
-
if (typeof window === "undefined" || typeof navigator === "undefined") return void 0;
|
|
12833
|
-
return {
|
|
12834
|
-
language: navigator.language,
|
|
12835
|
-
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
12836
|
-
cookiesEnabled: navigator.cookieEnabled,
|
|
12837
|
-
localStorage: typeof localStorage !== "undefined",
|
|
12838
|
-
online: navigator.onLine
|
|
12839
|
-
};
|
|
12840
|
-
}
|
|
12841
|
-
};
|
|
12842
|
-
var contextCapture = new ContextCaptureManager();
|
|
12843
12940
|
|
|
12844
12941
|
// src/BugBearProvider.tsx
|
|
12845
12942
|
import { Platform, Dimensions } from "react-native";
|
|
@@ -13040,6 +13137,7 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
13040
13137
|
useEffect(() => {
|
|
13041
13138
|
if (enabled && !hasInitialized.current) {
|
|
13042
13139
|
hasInitialized.current = true;
|
|
13140
|
+
contextCapture.startCapture();
|
|
13043
13141
|
const newClient = createBugBear(config);
|
|
13044
13142
|
setClient(newClient);
|
|
13045
13143
|
initializeBugBear(newClient);
|
|
@@ -14279,12 +14377,18 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14279
14377
|
const [reportType, setReportType] = useState6(prefill?.type || "bug");
|
|
14280
14378
|
const [severity, setSeverity] = useState6("medium");
|
|
14281
14379
|
const [description, setDescription] = useState6("");
|
|
14380
|
+
const [affectedScreen, setAffectedScreen] = useState6("");
|
|
14282
14381
|
const [submitting, setSubmitting] = useState6(false);
|
|
14283
14382
|
const images = useImageAttachments(uploadImage, 5, "screenshots");
|
|
14284
14383
|
const isBugType = reportType === "bug" || reportType === "test_fail";
|
|
14285
14384
|
const handleSubmit = async () => {
|
|
14286
14385
|
if (!client || !description.trim()) return;
|
|
14287
14386
|
setSubmitting(true);
|
|
14387
|
+
const baseContext = client.getAppContext();
|
|
14388
|
+
const appContext = {
|
|
14389
|
+
...baseContext,
|
|
14390
|
+
currentRoute: affectedScreen.trim() || baseContext.currentRoute
|
|
14391
|
+
};
|
|
14288
14392
|
const screenshotUrls = images.getScreenshotUrls();
|
|
14289
14393
|
await client.submitReport({
|
|
14290
14394
|
type: reportType,
|
|
@@ -14292,7 +14396,7 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14292
14396
|
severity: isBugType ? severity : void 0,
|
|
14293
14397
|
assignmentId: prefill?.assignmentId,
|
|
14294
14398
|
testCaseId: prefill?.testCaseId,
|
|
14295
|
-
appContext
|
|
14399
|
+
appContext,
|
|
14296
14400
|
deviceInfo: getDeviceInfo(),
|
|
14297
14401
|
screenshots: screenshotUrls.length > 0 ? screenshotUrls : void 0
|
|
14298
14402
|
});
|
|
@@ -14340,7 +14444,16 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14340
14444
|
numberOfLines: 4,
|
|
14341
14445
|
textAlignVertical: "top"
|
|
14342
14446
|
}
|
|
14343
|
-
)), /* @__PURE__ */ React8.createElement(
|
|
14447
|
+
)), isBugType && /* @__PURE__ */ React8.createElement(View7, { style: styles7.section }, /* @__PURE__ */ React8.createElement(Text7, { style: shared.label }, "Which screen?"), /* @__PURE__ */ React8.createElement(
|
|
14448
|
+
TextInput3,
|
|
14449
|
+
{
|
|
14450
|
+
style: styles7.screenInput,
|
|
14451
|
+
value: affectedScreen,
|
|
14452
|
+
onChangeText: setAffectedScreen,
|
|
14453
|
+
placeholder: "e.g. Reservations, Settings...",
|
|
14454
|
+
placeholderTextColor: colors.textMuted
|
|
14455
|
+
}
|
|
14456
|
+
), /* @__PURE__ */ React8.createElement(Text7, { style: styles7.screenHint }, "Which screen or area was the bug on? (optional)")), /* @__PURE__ */ React8.createElement(
|
|
14344
14457
|
ImagePickerButtons,
|
|
14345
14458
|
{
|
|
14346
14459
|
images: images.images,
|
|
@@ -14371,7 +14484,9 @@ var styles7 = StyleSheet8.create({
|
|
|
14371
14484
|
severityRow: { flexDirection: "row", gap: 8 },
|
|
14372
14485
|
sevButton: { flex: 1, paddingVertical: 8, borderRadius: 8, alignItems: "center", borderWidth: 1, borderColor: colors.border, backgroundColor: colors.card },
|
|
14373
14486
|
sevText: { fontSize: 12, fontWeight: "500", color: colors.textSecondary, textTransform: "capitalize" },
|
|
14374
|
-
descInput: { backgroundColor: colors.card, borderWidth: 1, borderColor: colors.border, borderRadius: 12, paddingHorizontal: 14, paddingVertical: 12, fontSize: 14, color: colors.textPrimary, minHeight: 100 }
|
|
14487
|
+
descInput: { backgroundColor: colors.card, borderWidth: 1, borderColor: colors.border, borderRadius: 12, paddingHorizontal: 14, paddingVertical: 12, fontSize: 14, color: colors.textPrimary, minHeight: 100 },
|
|
14488
|
+
screenInput: { backgroundColor: colors.card, borderWidth: 1, borderColor: colors.border, borderRadius: 8, paddingHorizontal: 12, paddingVertical: 8, fontSize: 13, color: colors.textPrimary },
|
|
14489
|
+
screenHint: { fontSize: 11, color: colors.textMuted, marginTop: 4 }
|
|
14375
14490
|
});
|
|
14376
14491
|
|
|
14377
14492
|
// src/widget/screens/ReportSuccessScreen.tsx
|