@bugspotter/sdk 2.0.5 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CONTRIBUTING.md CHANGED
@@ -190,9 +190,9 @@ pnpm build # Production build
190
190
 
191
191
  ## Getting Help
192
192
 
193
- - **Questions**: Open a [Discussion](https://github.com/apexbridge-tech/bugspotter-sdk/discussions)
194
- - **Bugs**: Open an [Issue](https://github.com/apexbridge-tech/bugspotter-sdk/issues) with the bug template
195
- - **Features**: Open an [Issue](https://github.com/apexbridge-tech/bugspotter-sdk/issues) with the feature template
193
+ - **Questions**: Open a [Discussion](https://github.com/apex-bridge/bugspotter-sdk/discussions)
194
+ - **Bugs**: Open an [Issue](https://github.com/apex-bridge/bugspotter-sdk/issues) with the bug template
195
+ - **Features**: Open an [Issue](https://github.com/apex-bridge/bugspotter-sdk/issues) with the feature template
196
196
  - **Security**: Email security@apexbridge.tech
197
197
 
198
198
  ## License
package/README.md CHANGED
@@ -38,8 +38,8 @@ pnpm add @bugspotter/sdk
38
38
 
39
39
  ```bash
40
40
  # Clone and build from source
41
- git clone https://github.com/apexbridge-tech/bugspotter.git
42
- cd bugspotter/packages/sdk
41
+ git clone https://github.com/apex-bridge/bugspotter-sdk.git
42
+ cd bugspotter-sdk
43
43
  pnpm install
44
44
  pnpm build
45
45
  ```
@@ -84,7 +84,7 @@ const bugSpotter = await BugSpotter.init({
84
84
  (async () => {
85
85
  const bugSpotter = await BugSpotter.init({
86
86
  endpoint: 'https://api.bugspotter.com',
87
- apiKey: 'bgs_your_api_key',
87
+ apiKey: 'bgs_your_api_key',
88
88
  showWidget: true,
89
89
  });
90
90
  })();
@@ -230,22 +230,84 @@ button.setBackgroundColor('#00ff00');
230
230
 
231
231
  ## 🔒 PII Sanitization
232
232
 
233
- Automatic detection and masking of sensitive data before submission.
233
+ Automatic detection and masking of sensitive text data **in the browser before upload**. When enabled (default), text fields (console logs, network URLs, metadata) are sanitized before submission. For visual exclusion: use `replay.blockSelectors` to hide DOM elements from session replay, and `data-bugspotter-exclude` attribute to exclude elements from screenshots.
234
+
235
+ ### Built-in Patterns (9 types)
236
+
237
+ | Pattern | Detects | Example |
238
+ | ------------ | ------------------------- | ----------------------------------------------- |
239
+ | `email` | Email addresses | `user@example.com` → `[REDACTED-EMAIL]` |
240
+ | `phone` | Phone numbers | `+7 701 123-4567` → `[REDACTED-PHONE]` |
241
+ | `creditcard` | Credit card numbers | `4111-1111-1111-1111` → `[REDACTED-CREDITCARD]` |
242
+ | `ssn` | US Social Security | `123-45-6789` → `[REDACTED-SSN]` |
243
+ | `iin` | Kazakhstan IIN/BIN | `860101350478` → `[REDACTED-IIN]` |
244
+ | `ip` | IPv4 and IPv6 | `192.168.1.1` → `[REDACTED-IP]` |
245
+ | `apikey` | Stripe, AWS, Google keys | `sk_live_...` → `[REDACTED-APIKEY]` |
246
+ | `token` | Bearer, JWT, OAuth tokens | `eyJhbG...` → `[REDACTED-TOKEN]` |
247
+ | `password` | Password field values | `••••••••` → `[REDACTED-PASSWORD]` |
248
+
249
+ ### Presets
250
+
251
+ Use a preset name instead of listing patterns individually:
252
+
253
+ | Preset | Patterns included |
254
+ | ------------------ | ----------------------- |
255
+ | `'all'` | All 9 patterns |
256
+ | `'minimal'` | email, creditcard, ssn |
257
+ | `'financial'` | creditcard, ssn |
258
+ | `'contact'` | email, phone |
259
+ | `'identification'` | ssn, iin |
260
+ | `'kazakhstan'` | email, phone, iin |
261
+ | `'gdpr'` | email, phone, ip |
262
+ | `'pci'` | creditcard |
263
+ | `'credentials'` | apikey, token, password |
234
264
 
235
- **Built-in patterns:** Email, phone, credit card, SSN, Kazakhstan IIN, IP address
265
+ ```javascript
266
+ // Use a preset
267
+ await BugSpotter.init({
268
+ sanitize: { patterns: 'kazakhstan' }, // email + phone + IIN
269
+ });
270
+
271
+ // Or pick individual patterns
272
+ await BugSpotter.init({
273
+ sanitize: { patterns: ['email', 'phone', 'creditcard'] },
274
+ });
275
+ ```
276
+
277
+ ### Custom Patterns
278
+
279
+ Add your own regex patterns for industry-specific data:
236
280
 
237
281
  ```javascript
238
282
  await BugSpotter.init({
239
283
  sanitize: {
240
- enabled: true, // Default
241
- patterns: ['email', 'phone', 'creditcard'],
242
- customPatterns: [{ name: 'api-key', regex: /API[-_]KEY:\s*[\w-]{20,}/gi }],
243
- excludeSelectors: ['.public-email'],
284
+ enabled: true,
285
+ patterns: 'all',
286
+ customPatterns: [
287
+ {
288
+ name: 'broker-account',
289
+ regex: /FRH\d{9}/gi,
290
+ description: 'Freedom Finance broker account number',
291
+ },
292
+ {
293
+ name: 'iban-kz',
294
+ regex: /KZ\d{2}[A-Z]{4}\d{13}/gi,
295
+ description: 'Kazakhstan IBAN',
296
+ },
297
+ {
298
+ name: 'internal-id',
299
+ regex: /ORD-\d{6,}/gi,
300
+ description: 'Internal order ID',
301
+ },
302
+ ],
303
+ excludeSelectors: ['.public-info'], // Don't redact inside these elements
244
304
  },
245
305
  });
246
306
  ```
247
307
 
248
- **Performance:** <10ms overhead, supports Cyrillic text
308
+ Custom patterns produce `[REDACTED-BROKER-ACCOUNT]`, `[REDACTED-IBAN-KZ]`, etc.
309
+
310
+ **Performance:** < 50ms overhead, recursive sanitization of nested objects, supports Cyrillic text
249
311
 
250
312
  ## 📋 API Reference
251
313
 
@@ -260,37 +322,58 @@ Initialize the SDK. **This method is async** to support fetching backend-control
260
322
  ```typescript
261
323
  interface BugSpotterConfig {
262
324
  apiKey: string; // Required: API key (bgs_...)
263
- endpoint?: string; // Base URL of BugSpotter API (e.g., https://api.example.com)
325
+ endpoint?: string; // Base URL of BugSpotter API
326
+ sampleRate?: number; // Session sampling (0-1, default: 1 = all sessions)
264
327
  showWidget?: boolean; // Auto-show widget (default: true)
265
328
  widgetOptions?: FloatingButtonOptions;
266
329
  replay?: {
267
- // Session replay configuration
268
330
  enabled?: boolean; // Enable replay (default: true)
269
331
  duration?: number; // Buffer duration in seconds (default: 15)
270
332
  sampling?: {
271
333
  mousemove?: number; // Mousemove throttle in ms (default: 50)
272
334
  scroll?: number; // Scroll throttle in ms (default: 100)
273
335
  };
336
+ blockSelectors?: string[]; // CSS selectors to exclude from replay
337
+ blockClass?: string; // CSS class to exclude from replay
274
338
  // Quality settings (optional, backend controlled by default)
275
- inlineStylesheet?: boolean; // Inline CSS stylesheets (default: backend controlled)
276
- inlineImages?: boolean; // Inline images (default: backend controlled)
277
- collectFonts?: boolean; // Collect fonts (default: backend controlled)
278
- recordCanvas?: boolean; // Record canvas elements (default: backend controlled)
279
- recordCrossOriginIframes?: boolean; // Record cross-origin iframes (default: backend controlled)
339
+ inlineStylesheet?: boolean;
340
+ inlineImages?: boolean;
341
+ collectFonts?: boolean;
342
+ recordCanvas?: boolean;
343
+ recordCrossOriginIframes?: boolean;
280
344
  };
281
345
  sanitize?: {
282
- // PII sanitization configuration
283
346
  enabled?: boolean; // Enable PII sanitization (default: true)
284
- patterns?: Array<
285
- // PII patterns to detect
286
- 'email' | 'phone' | 'creditcard' | 'ssn' | 'iin' | 'ip' | 'custom'
287
- >;
347
+ patterns?:
348
+ | 'all'
349
+ | 'minimal'
350
+ | 'financial'
351
+ | 'contact'
352
+ | 'identification'
353
+ | 'credentials'
354
+ | 'kazakhstan'
355
+ | 'gdpr'
356
+ | 'pci'
357
+ | Array<
358
+ | 'email'
359
+ | 'phone'
360
+ | 'creditcard'
361
+ | 'ssn'
362
+ | 'iin'
363
+ | 'ip'
364
+ | 'apikey'
365
+ | 'token'
366
+ | 'password'
367
+ | 'custom'
368
+ >;
288
369
  customPatterns?: Array<{
289
- // Custom regex patterns
290
- name: string; // Pattern name for [REDACTED-NAME]
370
+ name: string; // Pattern name → [REDACTED-NAME]
291
371
  regex: RegExp; // Detection regex
372
+ description?: string; // Human-readable description
373
+ examples?: string[]; // Example values for testing
374
+ priority?: number; // Pattern ordering hint (optional)
292
375
  }>;
293
- excludeSelectors?: string[]; // CSS selectors to exclude from sanitization
376
+ excludeSelectors?: string[]; // CSS selectors to exclude from DOM text sanitization (replay)
294
377
  };
295
378
  }
296
379
  ```
@@ -477,7 +560,9 @@ Upload screenshot directly to storage.
477
560
  const screenshotBlob = await fetch(dataUrl).then((r) => r.blob());
478
561
 
479
562
  const result = await uploader.uploadScreenshot(screenshotBlob, (progress) => {
480
- console.log(`Screenshot: ${progress.loaded}/${progress.total} (${progress.percentage}%)`);
563
+ console.log(
564
+ `Screenshot: ${progress.loaded}/${progress.total} (${progress.percentage}%)`
565
+ );
481
566
  });
482
567
 
483
568
  // result: { success: true, storageKey: "screenshots/..." }
@@ -667,7 +752,7 @@ Output: `dist/bugspotter.min.js` (~99 KB)
667
752
  - **Load**: < 100ms
668
753
  - **Memory**: < 15 MB (30s replay buffer)
669
754
  - **Screenshot**: ~500ms
670
- - **PII sanitization**: <10ms
755
+ - **PII sanitization**: <50ms
671
756
 
672
757
  ## 🔒 Security
673
758