@bbearai/core 0.4.4 → 0.4.6

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.d.mts CHANGED
@@ -3,7 +3,12 @@
3
3
  */
4
4
  type ReportType = 'bug' | 'feedback' | 'suggestion' | 'test_pass' | 'test_fail';
5
5
  type Severity = 'critical' | 'high' | 'medium' | 'low';
6
- type BugCategory = 'ui_ux' | 'functional' | 'crash' | 'security' | 'other';
6
+ /** Valid bug categories - single source of truth */
7
+ declare const BUG_CATEGORIES: readonly ["ui_ux", "functional", "crash", "security", "other"];
8
+ /** Bug category type derived from BUG_CATEGORIES */
9
+ type BugCategory = typeof BUG_CATEGORIES[number];
10
+ /** Type guard to check if a string is a valid BugCategory */
11
+ declare function isBugCategory(value: unknown): value is BugCategory;
7
12
  type ReportStatus = 'new' | 'triaging' | 'confirmed' | 'in_progress' | 'fixed' | 'ready_to_test' | 'verified' | 'resolved' | 'reviewed' | 'closed' | 'wont_fix' | 'duplicate';
8
13
  interface AppContext {
9
14
  /** Current route/screen path */
@@ -1068,4 +1073,4 @@ declare function captureError(error: Error, errorInfo?: {
1068
1073
  componentStack?: string;
1069
1074
  };
1070
1075
 
1071
- export { type AddFindingOptions, type AppContext, BugBearClient, type BugBearConfig, type BugBearReport, type BugBearTheme, type BugCategory, type ChecklistItem, type ChecklistResult, type ConsoleLogEntry, type CoverageGap, type CoverageMatrixCell, type CoverageMatrixRow, type DeployChecklist, type DeviceInfo, type EndSessionOptions, type EnhancedBugContext, type FindingSeverity, type FindingType, type HostUserInfo, type IssueCategory, type IssueCounts, type MessageSenderType, type NetworkRequest, type PriorityFactors, type ProjectRole, type QAFinding, type QAHealthMetrics, type QAHealthScore, type QASession, type QASessionStatus, type QATrack, type RegressionEvent, type ReportStatus, type ReportType, type RoutePriority, type RouteTestStats, type RubricMode, type RubricResult, type Severity, type SkipReason, type StartSessionOptions, type SubmitFeedbackOptions, type TestAssignment, type TestFeedback, type TestGroup, type TestResult, type TestStep, type TestTemplate, type TesterInfo, type TesterIssue, type TesterMessage, type TesterProfileUpdate, type TesterThread, type ThreadPriority, type ThreadType, captureError, contextCapture, createBugBear };
1076
+ export { type AddFindingOptions, type AppContext, BUG_CATEGORIES, BugBearClient, type BugBearConfig, type BugBearReport, type BugBearTheme, type BugCategory, type ChecklistItem, type ChecklistResult, type ConsoleLogEntry, type CoverageGap, type CoverageMatrixCell, type CoverageMatrixRow, type DeployChecklist, type DeviceInfo, type EndSessionOptions, type EnhancedBugContext, type FindingSeverity, type FindingType, type HostUserInfo, type IssueCategory, type IssueCounts, type MessageSenderType, type NetworkRequest, type PriorityFactors, type ProjectRole, type QAFinding, type QAHealthMetrics, type QAHealthScore, type QASession, type QASessionStatus, type QATrack, type RegressionEvent, type ReportStatus, type ReportType, type RoutePriority, type RouteTestStats, type RubricMode, type RubricResult, type Severity, type SkipReason, type StartSessionOptions, type SubmitFeedbackOptions, type TestAssignment, type TestFeedback, type TestGroup, type TestResult, type TestStep, type TestTemplate, type TesterInfo, type TesterIssue, type TesterMessage, type TesterProfileUpdate, type TesterThread, type ThreadPriority, type ThreadType, captureError, contextCapture, createBugBear, isBugCategory };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,12 @@
3
3
  */
4
4
  type ReportType = 'bug' | 'feedback' | 'suggestion' | 'test_pass' | 'test_fail';
5
5
  type Severity = 'critical' | 'high' | 'medium' | 'low';
6
- type BugCategory = 'ui_ux' | 'functional' | 'crash' | 'security' | 'other';
6
+ /** Valid bug categories - single source of truth */
7
+ declare const BUG_CATEGORIES: readonly ["ui_ux", "functional", "crash", "security", "other"];
8
+ /** Bug category type derived from BUG_CATEGORIES */
9
+ type BugCategory = typeof BUG_CATEGORIES[number];
10
+ /** Type guard to check if a string is a valid BugCategory */
11
+ declare function isBugCategory(value: unknown): value is BugCategory;
7
12
  type ReportStatus = 'new' | 'triaging' | 'confirmed' | 'in_progress' | 'fixed' | 'ready_to_test' | 'verified' | 'resolved' | 'reviewed' | 'closed' | 'wont_fix' | 'duplicate';
8
13
  interface AppContext {
9
14
  /** Current route/screen path */
@@ -1068,4 +1073,4 @@ declare function captureError(error: Error, errorInfo?: {
1068
1073
  componentStack?: string;
1069
1074
  };
1070
1075
 
1071
- export { type AddFindingOptions, type AppContext, BugBearClient, type BugBearConfig, type BugBearReport, type BugBearTheme, type BugCategory, type ChecklistItem, type ChecklistResult, type ConsoleLogEntry, type CoverageGap, type CoverageMatrixCell, type CoverageMatrixRow, type DeployChecklist, type DeviceInfo, type EndSessionOptions, type EnhancedBugContext, type FindingSeverity, type FindingType, type HostUserInfo, type IssueCategory, type IssueCounts, type MessageSenderType, type NetworkRequest, type PriorityFactors, type ProjectRole, type QAFinding, type QAHealthMetrics, type QAHealthScore, type QASession, type QASessionStatus, type QATrack, type RegressionEvent, type ReportStatus, type ReportType, type RoutePriority, type RouteTestStats, type RubricMode, type RubricResult, type Severity, type SkipReason, type StartSessionOptions, type SubmitFeedbackOptions, type TestAssignment, type TestFeedback, type TestGroup, type TestResult, type TestStep, type TestTemplate, type TesterInfo, type TesterIssue, type TesterMessage, type TesterProfileUpdate, type TesterThread, type ThreadPriority, type ThreadType, captureError, contextCapture, createBugBear };
1076
+ export { type AddFindingOptions, type AppContext, BUG_CATEGORIES, BugBearClient, type BugBearConfig, type BugBearReport, type BugBearTheme, type BugCategory, type ChecklistItem, type ChecklistResult, type ConsoleLogEntry, type CoverageGap, type CoverageMatrixCell, type CoverageMatrixRow, type DeployChecklist, type DeviceInfo, type EndSessionOptions, type EnhancedBugContext, type FindingSeverity, type FindingType, type HostUserInfo, type IssueCategory, type IssueCounts, type MessageSenderType, type NetworkRequest, type PriorityFactors, type ProjectRole, type QAFinding, type QAHealthMetrics, type QAHealthScore, type QASession, type QASessionStatus, type QATrack, type RegressionEvent, type ReportStatus, type ReportType, type RoutePriority, type RouteTestStats, type RubricMode, type RubricResult, type Severity, type SkipReason, type StartSessionOptions, type SubmitFeedbackOptions, type TestAssignment, type TestFeedback, type TestGroup, type TestResult, type TestStep, type TestTemplate, type TesterInfo, type TesterIssue, type TesterMessage, type TesterProfileUpdate, type TesterThread, type ThreadPriority, type ThreadType, captureError, contextCapture, createBugBear, isBugCategory };
package/dist/index.js CHANGED
@@ -20,13 +20,21 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ BUG_CATEGORIES: () => BUG_CATEGORIES,
23
24
  BugBearClient: () => BugBearClient,
24
25
  captureError: () => captureError,
25
26
  contextCapture: () => contextCapture,
26
- createBugBear: () => createBugBear
27
+ createBugBear: () => createBugBear,
28
+ isBugCategory: () => isBugCategory
27
29
  });
28
30
  module.exports = __toCommonJS(index_exports);
29
31
 
32
+ // src/types.ts
33
+ var BUG_CATEGORIES = ["ui_ux", "functional", "crash", "security", "other"];
34
+ function isBugCategory(value) {
35
+ return typeof value === "string" && BUG_CATEGORIES.includes(value);
36
+ }
37
+
30
38
  // src/client.ts
31
39
  var import_supabase_js = require("@supabase/supabase-js");
32
40
 
@@ -467,7 +475,13 @@ var BugBearClient = class {
467
475
  console.error("BugBear: Failed to fetch assignments", formatPgError(error));
468
476
  return [];
469
477
  }
470
- const mapped = (data || []).map((item) => ({
478
+ const mapped = (data || []).filter((item) => {
479
+ if (!item.test_case) {
480
+ console.warn("BugBear: Assignment returned without test_case", { id: item.id });
481
+ return false;
482
+ }
483
+ return true;
484
+ }).map((item) => ({
471
485
  id: item.id,
472
486
  status: item.status,
473
487
  startedAt: item.started_at,
@@ -724,6 +738,16 @@ var BugBearClient = class {
724
738
  if (feedback.rating < 1 || feedback.rating > 5) {
725
739
  return { success: false, error: "Rating must be between 1 and 5" };
726
740
  }
741
+ const optionalRatings = [
742
+ { name: "clarityRating", value: feedback.clarityRating },
743
+ { name: "stepsRating", value: feedback.stepsRating },
744
+ { name: "relevanceRating", value: feedback.relevanceRating }
745
+ ];
746
+ for (const { name, value } of optionalRatings) {
747
+ if (value !== void 0 && value !== null && (value < 1 || value > 5)) {
748
+ return { success: false, error: `${name} must be between 1 and 5` };
749
+ }
750
+ }
727
751
  const { error: feedbackError } = await this.supabase.from("test_feedback").insert({
728
752
  project_id: this.config.projectId,
729
753
  test_case_id: testCaseId,
@@ -975,9 +999,8 @@ var BugBearClient = class {
975
999
  if (report.severity && !validSeverities.includes(report.severity)) {
976
1000
  return `Invalid severity: ${report.severity}. Must be one of: ${validSeverities.join(", ")}`;
977
1001
  }
978
- const validCategories = ["ui_ux", "functional", "crash", "security", "other"];
979
- if (report.category && !validCategories.includes(report.category)) {
980
- return `Invalid category: ${report.category}. Must be one of: ${validCategories.join(", ")}`;
1002
+ if (report.category && !BUG_CATEGORIES.includes(report.category)) {
1003
+ return `Invalid category: ${report.category}. Must be one of: ${BUG_CATEGORIES.join(", ")}`;
981
1004
  }
982
1005
  if (report.title && report.title.length > 500) {
983
1006
  return "Title must be 500 characters or less";
@@ -1051,6 +1074,10 @@ var BugBearClient = class {
1051
1074
  });
1052
1075
  if (error) {
1053
1076
  console.warn("BugBear: Rate limit check failed, allowing request", error.message);
1077
+ this.config.onError?.(new Error(`Rate limit check failed: ${error.message}`), {
1078
+ projectId: this.config.projectId,
1079
+ context: "rate_limit_check_failed_open"
1080
+ });
1054
1081
  return { allowed: true };
1055
1082
  }
1056
1083
  if (!data.allowed) {
@@ -1067,7 +1094,12 @@ var BugBearClient = class {
1067
1094
  resetAt: data.reset_at
1068
1095
  };
1069
1096
  } catch (err) {
1097
+ const message = err instanceof Error ? err.message : "Unknown rate limit error";
1070
1098
  console.warn("BugBear: Rate limit check error", err);
1099
+ this.config.onError?.(err instanceof Error ? err : new Error(message), {
1100
+ projectId: this.config.projectId,
1101
+ context: "rate_limit_check_failed_open"
1102
+ });
1071
1103
  return { allowed: true };
1072
1104
  }
1073
1105
  }
@@ -1131,6 +1163,9 @@ var BugBearClient = class {
1131
1163
  }
1132
1164
  return data ?? true;
1133
1165
  } catch (err) {
1166
+ const message = err instanceof Error ? err.message : "Unknown error checking QA status";
1167
+ console.error("BugBear: Error checking QA status", err);
1168
+ this.config.onError?.(err instanceof Error ? err : new Error(message), { projectId: this.config.projectId });
1134
1169
  return true;
1135
1170
  }
1136
1171
  }
@@ -1159,13 +1194,24 @@ var BugBearClient = class {
1159
1194
  upsert: false
1160
1195
  });
1161
1196
  if (error) {
1162
- console.error("BugBear: Failed to upload screenshot", formatPgError(error));
1197
+ const formattedError = formatPgError(error);
1198
+ const errorMessage = formattedError.message || "Failed to upload screenshot";
1199
+ console.error("BugBear: Failed to upload screenshot", formattedError);
1200
+ this.config.onError?.(new Error(errorMessage), {
1201
+ projectId: this.config.projectId,
1202
+ context: "screenshot_upload_failed"
1203
+ });
1163
1204
  return null;
1164
1205
  }
1165
1206
  const { data: { publicUrl } } = this.supabase.storage.from(bucket).getPublicUrl(path);
1166
1207
  return publicUrl;
1167
1208
  } catch (err) {
1209
+ const message = err instanceof Error ? err.message : "Unknown error uploading screenshot";
1168
1210
  console.error("BugBear: Error uploading screenshot", err);
1211
+ this.config.onError?.(err instanceof Error ? err : new Error(message), {
1212
+ projectId: this.config.projectId,
1213
+ context: "screenshot_upload_failed"
1214
+ });
1169
1215
  return null;
1170
1216
  }
1171
1217
  }
@@ -1190,13 +1236,24 @@ var BugBearClient = class {
1190
1236
  upsert: false
1191
1237
  });
1192
1238
  if (error) {
1193
- console.error("BugBear: Failed to upload image from URI", formatPgError(error));
1239
+ const formattedError = formatPgError(error);
1240
+ const errorMessage = formattedError.message || "Failed to upload image";
1241
+ console.error("BugBear: Failed to upload image from URI", formattedError);
1242
+ this.config.onError?.(new Error(errorMessage), {
1243
+ projectId: this.config.projectId,
1244
+ context: "image_upload_failed"
1245
+ });
1194
1246
  return null;
1195
1247
  }
1196
1248
  const { data: { publicUrl } } = this.supabase.storage.from(bucket).getPublicUrl(path);
1197
1249
  return publicUrl;
1198
1250
  } catch (err) {
1251
+ const message = err instanceof Error ? err.message : "Unknown error uploading image";
1199
1252
  console.error("BugBear: Error uploading image from URI", err);
1253
+ this.config.onError?.(err instanceof Error ? err : new Error(message), {
1254
+ projectId: this.config.projectId,
1255
+ context: "image_upload_failed"
1256
+ });
1200
1257
  return null;
1201
1258
  }
1202
1259
  }
@@ -1727,8 +1784,10 @@ function createBugBear(config) {
1727
1784
  }
1728
1785
  // Annotate the CommonJS export names for ESM import in node:
1729
1786
  0 && (module.exports = {
1787
+ BUG_CATEGORIES,
1730
1788
  BugBearClient,
1731
1789
  captureError,
1732
1790
  contextCapture,
1733
- createBugBear
1791
+ createBugBear,
1792
+ isBugCategory
1734
1793
  });
package/dist/index.mjs CHANGED
@@ -1,3 +1,9 @@
1
+ // src/types.ts
2
+ var BUG_CATEGORIES = ["ui_ux", "functional", "crash", "security", "other"];
3
+ function isBugCategory(value) {
4
+ return typeof value === "string" && BUG_CATEGORIES.includes(value);
5
+ }
6
+
1
7
  // src/client.ts
2
8
  import { createClient } from "@supabase/supabase-js";
3
9
 
@@ -438,7 +444,13 @@ var BugBearClient = class {
438
444
  console.error("BugBear: Failed to fetch assignments", formatPgError(error));
439
445
  return [];
440
446
  }
441
- const mapped = (data || []).map((item) => ({
447
+ const mapped = (data || []).filter((item) => {
448
+ if (!item.test_case) {
449
+ console.warn("BugBear: Assignment returned without test_case", { id: item.id });
450
+ return false;
451
+ }
452
+ return true;
453
+ }).map((item) => ({
442
454
  id: item.id,
443
455
  status: item.status,
444
456
  startedAt: item.started_at,
@@ -695,6 +707,16 @@ var BugBearClient = class {
695
707
  if (feedback.rating < 1 || feedback.rating > 5) {
696
708
  return { success: false, error: "Rating must be between 1 and 5" };
697
709
  }
710
+ const optionalRatings = [
711
+ { name: "clarityRating", value: feedback.clarityRating },
712
+ { name: "stepsRating", value: feedback.stepsRating },
713
+ { name: "relevanceRating", value: feedback.relevanceRating }
714
+ ];
715
+ for (const { name, value } of optionalRatings) {
716
+ if (value !== void 0 && value !== null && (value < 1 || value > 5)) {
717
+ return { success: false, error: `${name} must be between 1 and 5` };
718
+ }
719
+ }
698
720
  const { error: feedbackError } = await this.supabase.from("test_feedback").insert({
699
721
  project_id: this.config.projectId,
700
722
  test_case_id: testCaseId,
@@ -946,9 +968,8 @@ var BugBearClient = class {
946
968
  if (report.severity && !validSeverities.includes(report.severity)) {
947
969
  return `Invalid severity: ${report.severity}. Must be one of: ${validSeverities.join(", ")}`;
948
970
  }
949
- const validCategories = ["ui_ux", "functional", "crash", "security", "other"];
950
- if (report.category && !validCategories.includes(report.category)) {
951
- return `Invalid category: ${report.category}. Must be one of: ${validCategories.join(", ")}`;
971
+ if (report.category && !BUG_CATEGORIES.includes(report.category)) {
972
+ return `Invalid category: ${report.category}. Must be one of: ${BUG_CATEGORIES.join(", ")}`;
952
973
  }
953
974
  if (report.title && report.title.length > 500) {
954
975
  return "Title must be 500 characters or less";
@@ -1022,6 +1043,10 @@ var BugBearClient = class {
1022
1043
  });
1023
1044
  if (error) {
1024
1045
  console.warn("BugBear: Rate limit check failed, allowing request", error.message);
1046
+ this.config.onError?.(new Error(`Rate limit check failed: ${error.message}`), {
1047
+ projectId: this.config.projectId,
1048
+ context: "rate_limit_check_failed_open"
1049
+ });
1025
1050
  return { allowed: true };
1026
1051
  }
1027
1052
  if (!data.allowed) {
@@ -1038,7 +1063,12 @@ var BugBearClient = class {
1038
1063
  resetAt: data.reset_at
1039
1064
  };
1040
1065
  } catch (err) {
1066
+ const message = err instanceof Error ? err.message : "Unknown rate limit error";
1041
1067
  console.warn("BugBear: Rate limit check error", err);
1068
+ this.config.onError?.(err instanceof Error ? err : new Error(message), {
1069
+ projectId: this.config.projectId,
1070
+ context: "rate_limit_check_failed_open"
1071
+ });
1042
1072
  return { allowed: true };
1043
1073
  }
1044
1074
  }
@@ -1102,6 +1132,9 @@ var BugBearClient = class {
1102
1132
  }
1103
1133
  return data ?? true;
1104
1134
  } catch (err) {
1135
+ const message = err instanceof Error ? err.message : "Unknown error checking QA status";
1136
+ console.error("BugBear: Error checking QA status", err);
1137
+ this.config.onError?.(err instanceof Error ? err : new Error(message), { projectId: this.config.projectId });
1105
1138
  return true;
1106
1139
  }
1107
1140
  }
@@ -1130,13 +1163,24 @@ var BugBearClient = class {
1130
1163
  upsert: false
1131
1164
  });
1132
1165
  if (error) {
1133
- console.error("BugBear: Failed to upload screenshot", formatPgError(error));
1166
+ const formattedError = formatPgError(error);
1167
+ const errorMessage = formattedError.message || "Failed to upload screenshot";
1168
+ console.error("BugBear: Failed to upload screenshot", formattedError);
1169
+ this.config.onError?.(new Error(errorMessage), {
1170
+ projectId: this.config.projectId,
1171
+ context: "screenshot_upload_failed"
1172
+ });
1134
1173
  return null;
1135
1174
  }
1136
1175
  const { data: { publicUrl } } = this.supabase.storage.from(bucket).getPublicUrl(path);
1137
1176
  return publicUrl;
1138
1177
  } catch (err) {
1178
+ const message = err instanceof Error ? err.message : "Unknown error uploading screenshot";
1139
1179
  console.error("BugBear: Error uploading screenshot", err);
1180
+ this.config.onError?.(err instanceof Error ? err : new Error(message), {
1181
+ projectId: this.config.projectId,
1182
+ context: "screenshot_upload_failed"
1183
+ });
1140
1184
  return null;
1141
1185
  }
1142
1186
  }
@@ -1161,13 +1205,24 @@ var BugBearClient = class {
1161
1205
  upsert: false
1162
1206
  });
1163
1207
  if (error) {
1164
- console.error("BugBear: Failed to upload image from URI", formatPgError(error));
1208
+ const formattedError = formatPgError(error);
1209
+ const errorMessage = formattedError.message || "Failed to upload image";
1210
+ console.error("BugBear: Failed to upload image from URI", formattedError);
1211
+ this.config.onError?.(new Error(errorMessage), {
1212
+ projectId: this.config.projectId,
1213
+ context: "image_upload_failed"
1214
+ });
1165
1215
  return null;
1166
1216
  }
1167
1217
  const { data: { publicUrl } } = this.supabase.storage.from(bucket).getPublicUrl(path);
1168
1218
  return publicUrl;
1169
1219
  } catch (err) {
1220
+ const message = err instanceof Error ? err.message : "Unknown error uploading image";
1170
1221
  console.error("BugBear: Error uploading image from URI", err);
1222
+ this.config.onError?.(err instanceof Error ? err : new Error(message), {
1223
+ projectId: this.config.projectId,
1224
+ context: "image_upload_failed"
1225
+ });
1171
1226
  return null;
1172
1227
  }
1173
1228
  }
@@ -1697,8 +1752,10 @@ function createBugBear(config) {
1697
1752
  return new BugBearClient(config);
1698
1753
  }
1699
1754
  export {
1755
+ BUG_CATEGORIES,
1700
1756
  BugBearClient,
1701
1757
  captureError,
1702
1758
  contextCapture,
1703
- createBugBear
1759
+ createBugBear,
1760
+ isBugCategory
1704
1761
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbearai/core",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "description": "Core utilities and types for BugBear QA platform",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",