@bbearai/core 0.3.1 → 0.4.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/dist/index.d.mts CHANGED
@@ -187,6 +187,15 @@ interface TestGroup {
187
187
  description?: string;
188
188
  sortOrder: number;
189
189
  }
190
+ /** Project role — a user role in the app under test (e.g., Owner, Manager) */
191
+ interface ProjectRole {
192
+ id: string;
193
+ name: string;
194
+ slug: string;
195
+ color: string;
196
+ description?: string;
197
+ loginHint?: string;
198
+ }
190
199
  interface QATrack {
191
200
  id: string;
192
201
  name: string;
@@ -212,6 +221,8 @@ interface TestAssignment {
212
221
  track?: QATrack;
213
222
  /** Test group (folder) this test belongs to */
214
223
  group?: TestGroup;
224
+ /** Required app role for testing (e.g., Owner, Manager) */
225
+ role?: ProjectRole;
215
226
  };
216
227
  status: 'pending' | 'in_progress' | 'passed' | 'failed' | 'blocked' | 'skipped';
217
228
  /** Reason for skipping (when status is 'skipped') */
@@ -609,6 +620,7 @@ declare class BugBearClient {
609
620
  private supabase;
610
621
  private config;
611
622
  private navigationHistory;
623
+ private reportSubmitInFlight;
612
624
  constructor(config: BugBearConfig);
613
625
  /**
614
626
  * Track navigation for context.
@@ -1007,4 +1019,4 @@ declare function captureError(error: Error, errorInfo?: {
1007
1019
  componentStack?: string;
1008
1020
  };
1009
1021
 
1010
- export { type AddFindingOptions, type AppContext, BugBearClient, type BugBearConfig, type BugBearReport, type BugBearTheme, 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 MessageSenderType, type NetworkRequest, type PriorityFactors, 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 TesterMessage, type TesterProfileUpdate, type TesterThread, type ThreadPriority, type ThreadType, captureError, contextCapture, createBugBear };
1022
+ export { type AddFindingOptions, type AppContext, BugBearClient, type BugBearConfig, type BugBearReport, type BugBearTheme, 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 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 TesterMessage, type TesterProfileUpdate, type TesterThread, type ThreadPriority, type ThreadType, captureError, contextCapture, createBugBear };
package/dist/index.d.ts CHANGED
@@ -187,6 +187,15 @@ interface TestGroup {
187
187
  description?: string;
188
188
  sortOrder: number;
189
189
  }
190
+ /** Project role — a user role in the app under test (e.g., Owner, Manager) */
191
+ interface ProjectRole {
192
+ id: string;
193
+ name: string;
194
+ slug: string;
195
+ color: string;
196
+ description?: string;
197
+ loginHint?: string;
198
+ }
190
199
  interface QATrack {
191
200
  id: string;
192
201
  name: string;
@@ -212,6 +221,8 @@ interface TestAssignment {
212
221
  track?: QATrack;
213
222
  /** Test group (folder) this test belongs to */
214
223
  group?: TestGroup;
224
+ /** Required app role for testing (e.g., Owner, Manager) */
225
+ role?: ProjectRole;
215
226
  };
216
227
  status: 'pending' | 'in_progress' | 'passed' | 'failed' | 'blocked' | 'skipped';
217
228
  /** Reason for skipping (when status is 'skipped') */
@@ -609,6 +620,7 @@ declare class BugBearClient {
609
620
  private supabase;
610
621
  private config;
611
622
  private navigationHistory;
623
+ private reportSubmitInFlight;
612
624
  constructor(config: BugBearConfig);
613
625
  /**
614
626
  * Track navigation for context.
@@ -1007,4 +1019,4 @@ declare function captureError(error: Error, errorInfo?: {
1007
1019
  componentStack?: string;
1008
1020
  };
1009
1021
 
1010
- export { type AddFindingOptions, type AppContext, BugBearClient, type BugBearConfig, type BugBearReport, type BugBearTheme, 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 MessageSenderType, type NetworkRequest, type PriorityFactors, 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 TesterMessage, type TesterProfileUpdate, type TesterThread, type ThreadPriority, type ThreadType, captureError, contextCapture, createBugBear };
1022
+ export { type AddFindingOptions, type AppContext, BugBearClient, type BugBearConfig, type BugBearReport, type BugBearTheme, 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 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 TesterMessage, type TesterProfileUpdate, type TesterThread, type ThreadPriority, type ThreadType, captureError, contextCapture, createBugBear };
package/dist/index.js CHANGED
@@ -292,6 +292,7 @@ var HOSTED_BUGBEAR_ANON_KEY = getEnvVar("BUGBEAR_ANON_KEY") || getEnvVar("NEXT_P
292
292
  var BugBearClient = class {
293
293
  constructor(config) {
294
294
  this.navigationHistory = [];
295
+ this.reportSubmitInFlight = false;
295
296
  this.config = config;
296
297
  this.supabase = (0, import_supabase_js.createClient)(
297
298
  config.supabaseUrl || DEFAULT_SUPABASE_URL,
@@ -352,6 +353,10 @@ var BugBearClient = class {
352
353
  * Submit a report
353
354
  */
354
355
  async submitReport(report) {
356
+ if (this.reportSubmitInFlight) {
357
+ return { success: false, error: "A report is already being submitted" };
358
+ }
359
+ this.reportSubmitInFlight = true;
355
360
  try {
356
361
  const validationError = this.validateReport(report);
357
362
  if (validationError) {
@@ -403,6 +408,8 @@ var BugBearClient = class {
403
408
  } catch (err) {
404
409
  const message = err instanceof Error ? err.message : "Unknown error";
405
410
  return { success: false, error: message };
411
+ } finally {
412
+ this.reportSubmitInFlight = false;
406
413
  }
407
414
  }
408
415
  /**
@@ -443,6 +450,14 @@ var BugBearClient = class {
443
450
  name,
444
451
  description,
445
452
  sort_order
453
+ ),
454
+ role:project_roles(
455
+ id,
456
+ name,
457
+ slug,
458
+ color,
459
+ description,
460
+ login_hint
446
461
  )
447
462
  )
448
463
  `).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).in("status", ["pending", "in_progress"]).order("created_at", { ascending: true }).limit(100);
@@ -480,6 +495,14 @@ var BugBearClient = class {
480
495
  name: item.test_case.group.name,
481
496
  description: item.test_case.group.description,
482
497
  sortOrder: item.test_case.group.sort_order
498
+ } : void 0,
499
+ role: item.test_case.role ? {
500
+ id: item.test_case.role.id,
501
+ name: item.test_case.role.name,
502
+ slug: item.test_case.role.slug,
503
+ color: item.test_case.role.color,
504
+ description: item.test_case.role.description,
505
+ loginHint: item.test_case.role.login_hint
483
506
  } : void 0
484
507
  }
485
508
  }));
@@ -895,8 +918,8 @@ var BugBearClient = class {
895
918
  return "Maximum 10 screenshots allowed";
896
919
  }
897
920
  for (const url of report.screenshots) {
898
- if (typeof url !== "string" || url.length > 2e3) {
899
- return "Invalid screenshot URL";
921
+ if (typeof url !== "string" || url.length > 2e3 || !/^https?:\/\//i.test(url)) {
922
+ return "Invalid screenshot URL (must be an HTTP/HTTPS URL)";
900
923
  }
901
924
  }
902
925
  }
@@ -1285,7 +1308,10 @@ var BugBearClient = class {
1285
1308
  content
1286
1309
  };
1287
1310
  if (attachments && attachments.length > 0) {
1288
- insertData.attachments = attachments;
1311
+ const safeAttachments = attachments.filter((a) => /^https?:\/\//i.test(a.url));
1312
+ if (safeAttachments.length > 0) {
1313
+ insertData.attachments = safeAttachments;
1314
+ }
1289
1315
  }
1290
1316
  const { error } = await this.supabase.from("discussion_messages").insert(insertData);
1291
1317
  if (error) {
package/dist/index.mjs CHANGED
@@ -263,6 +263,7 @@ var HOSTED_BUGBEAR_ANON_KEY = getEnvVar("BUGBEAR_ANON_KEY") || getEnvVar("NEXT_P
263
263
  var BugBearClient = class {
264
264
  constructor(config) {
265
265
  this.navigationHistory = [];
266
+ this.reportSubmitInFlight = false;
266
267
  this.config = config;
267
268
  this.supabase = createClient(
268
269
  config.supabaseUrl || DEFAULT_SUPABASE_URL,
@@ -323,6 +324,10 @@ var BugBearClient = class {
323
324
  * Submit a report
324
325
  */
325
326
  async submitReport(report) {
327
+ if (this.reportSubmitInFlight) {
328
+ return { success: false, error: "A report is already being submitted" };
329
+ }
330
+ this.reportSubmitInFlight = true;
326
331
  try {
327
332
  const validationError = this.validateReport(report);
328
333
  if (validationError) {
@@ -374,6 +379,8 @@ var BugBearClient = class {
374
379
  } catch (err) {
375
380
  const message = err instanceof Error ? err.message : "Unknown error";
376
381
  return { success: false, error: message };
382
+ } finally {
383
+ this.reportSubmitInFlight = false;
377
384
  }
378
385
  }
379
386
  /**
@@ -414,6 +421,14 @@ var BugBearClient = class {
414
421
  name,
415
422
  description,
416
423
  sort_order
424
+ ),
425
+ role:project_roles(
426
+ id,
427
+ name,
428
+ slug,
429
+ color,
430
+ description,
431
+ login_hint
417
432
  )
418
433
  )
419
434
  `).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).in("status", ["pending", "in_progress"]).order("created_at", { ascending: true }).limit(100);
@@ -451,6 +466,14 @@ var BugBearClient = class {
451
466
  name: item.test_case.group.name,
452
467
  description: item.test_case.group.description,
453
468
  sortOrder: item.test_case.group.sort_order
469
+ } : void 0,
470
+ role: item.test_case.role ? {
471
+ id: item.test_case.role.id,
472
+ name: item.test_case.role.name,
473
+ slug: item.test_case.role.slug,
474
+ color: item.test_case.role.color,
475
+ description: item.test_case.role.description,
476
+ loginHint: item.test_case.role.login_hint
454
477
  } : void 0
455
478
  }
456
479
  }));
@@ -866,8 +889,8 @@ var BugBearClient = class {
866
889
  return "Maximum 10 screenshots allowed";
867
890
  }
868
891
  for (const url of report.screenshots) {
869
- if (typeof url !== "string" || url.length > 2e3) {
870
- return "Invalid screenshot URL";
892
+ if (typeof url !== "string" || url.length > 2e3 || !/^https?:\/\//i.test(url)) {
893
+ return "Invalid screenshot URL (must be an HTTP/HTTPS URL)";
871
894
  }
872
895
  }
873
896
  }
@@ -1256,7 +1279,10 @@ var BugBearClient = class {
1256
1279
  content
1257
1280
  };
1258
1281
  if (attachments && attachments.length > 0) {
1259
- insertData.attachments = attachments;
1282
+ const safeAttachments = attachments.filter((a) => /^https?:\/\//i.test(a.url));
1283
+ if (safeAttachments.length > 0) {
1284
+ insertData.attachments = safeAttachments;
1285
+ }
1260
1286
  }
1261
1287
  const { error } = await this.supabase.from("discussion_messages").insert(insertData);
1262
1288
  if (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbearai/core",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "Core utilities and types for BugBear QA platform",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",