@bugspotter/sdk 2.0.0 → 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 +3 -3
- package/README.md +125 -70
- package/dist/bugspotter.min.js +1 -1
- package/dist/bugspotter.min.js.map +1 -1
- package/dist/collectors/dom.d.ts +4 -0
- package/dist/collectors/dom.js +13 -14
- package/dist/core/bug-reporter.js +6 -4
- package/dist/core/capture-manager.d.ts +2 -0
- package/dist/core/capture-manager.js +3 -1
- package/dist/index.d.ts +31 -10
- package/dist/index.esm.js +103 -47
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +52 -10
- package/dist/utils/config-validator.d.ts +2 -3
- package/dist/utils/config-validator.js +3 -7
- package/dist/utils/sanitize.js +25 -10
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/CDN.md +3 -3
- package/docs/FRAMEWORK_INTEGRATION.md +1 -1
- package/eslint.config.js +7 -0
- package/package.json +4 -4
- package/release_notes.md +1 -1
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/
|
|
194
|
-
- **Bugs**: Open an [Issue](https://github.com/
|
|
195
|
-
- **Features**: Open an [Issue](https://github.com/
|
|
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
|
@@ -23,7 +23,7 @@ pnpm add @bugspotter/sdk
|
|
|
23
23
|
|
|
24
24
|
```html
|
|
25
25
|
<!-- BugSpotter CDN (versioned - recommended for production) -->
|
|
26
|
-
<script src="https://cdn.bugspotter.io/sdk/bugspotter-
|
|
26
|
+
<script src="https://cdn.bugspotter.io/sdk/bugspotter-2.0.0.min.js"></script>
|
|
27
27
|
|
|
28
28
|
<!-- Latest version (for development only) -->
|
|
29
29
|
<script src="https://cdn.bugspotter.io/sdk/bugspotter-latest.min.js"></script>
|
|
@@ -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/
|
|
42
|
-
cd bugspotter
|
|
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
|
```
|
|
@@ -57,12 +57,8 @@ import BugSpotter from '@bugspotter/sdk';
|
|
|
57
57
|
|
|
58
58
|
// Initialize with auto-widget (note: init is async)
|
|
59
59
|
const bugSpotter = await BugSpotter.init({
|
|
60
|
-
endpoint: 'https://api.bugspotter.com
|
|
61
|
-
|
|
62
|
-
type: 'api-key',
|
|
63
|
-
apiKey: 'bgs_your_api_key',
|
|
64
|
-
projectId: 'your-project-uuid',
|
|
65
|
-
},
|
|
60
|
+
endpoint: 'https://api.bugspotter.com',
|
|
61
|
+
apiKey: 'bgs_your_api_key',
|
|
66
62
|
showWidget: true,
|
|
67
63
|
});
|
|
68
64
|
```
|
|
@@ -73,12 +69,8 @@ const bugSpotter = await BugSpotter.init({
|
|
|
73
69
|
const BugSpotter = require('@bugspotter/sdk');
|
|
74
70
|
|
|
75
71
|
const bugSpotter = await BugSpotter.init({
|
|
76
|
-
endpoint: 'https://api.bugspotter.com
|
|
77
|
-
|
|
78
|
-
type: 'api-key',
|
|
79
|
-
apiKey: 'bgs_your_api_key',
|
|
80
|
-
projectId: 'your-project-uuid',
|
|
81
|
-
},
|
|
72
|
+
endpoint: 'https://api.bugspotter.com',
|
|
73
|
+
apiKey: 'bgs_your_api_key',
|
|
82
74
|
showWidget: true,
|
|
83
75
|
});
|
|
84
76
|
```
|
|
@@ -91,12 +83,8 @@ const bugSpotter = await BugSpotter.init({
|
|
|
91
83
|
// Initialize with auto-widget
|
|
92
84
|
(async () => {
|
|
93
85
|
const bugSpotter = await BugSpotter.init({
|
|
94
|
-
endpoint: 'https://api.bugspotter.com
|
|
95
|
-
|
|
96
|
-
type: 'api-key',
|
|
97
|
-
apiKey: 'bgs_your_api_key',
|
|
98
|
-
projectId: 'your-project-uuid',
|
|
99
|
-
},
|
|
86
|
+
endpoint: 'https://api.bugspotter.com',
|
|
87
|
+
apiKey: 'bgs_your_api_key',
|
|
100
88
|
showWidget: true,
|
|
101
89
|
});
|
|
102
90
|
})();
|
|
@@ -112,12 +100,8 @@ import BugSpotter from '@bugspotter/sdk';
|
|
|
112
100
|
|
|
113
101
|
// 1. Initialize SDK with required auth
|
|
114
102
|
const bugSpotter = await BugSpotter.init({
|
|
115
|
-
endpoint: 'https://api.bugspotter.com
|
|
116
|
-
|
|
117
|
-
type: 'api-key',
|
|
118
|
-
apiKey: 'bgs_your_api_key',
|
|
119
|
-
projectId: 'your-project-uuid', // Required for file uploads
|
|
120
|
-
},
|
|
103
|
+
endpoint: 'https://api.bugspotter.com',
|
|
104
|
+
apiKey: 'bgs_your_api_key',
|
|
121
105
|
showWidget: true,
|
|
122
106
|
});
|
|
123
107
|
|
|
@@ -142,12 +126,8 @@ const bugSpotter = await BugSpotter.init({
|
|
|
142
126
|
```javascript
|
|
143
127
|
// Initialize without widget
|
|
144
128
|
const bugSpotter = await BugSpotter.init({
|
|
145
|
-
endpoint: 'https://api.bugspotter.com
|
|
146
|
-
|
|
147
|
-
type: 'api-key',
|
|
148
|
-
apiKey: 'bgs_your_api_key',
|
|
149
|
-
projectId: 'your-project-uuid',
|
|
150
|
-
},
|
|
129
|
+
endpoint: 'https://api.bugspotter.com',
|
|
130
|
+
apiKey: 'bgs_your_api_key',
|
|
151
131
|
showWidget: false,
|
|
152
132
|
});
|
|
153
133
|
|
|
@@ -177,12 +157,8 @@ await bugSpotter.submit({
|
|
|
177
157
|
```javascript
|
|
178
158
|
// Widget appears automatically with showWidget: true
|
|
179
159
|
const bugSpotter = await BugSpotter.init({
|
|
180
|
-
endpoint: 'https://api.bugspotter.com
|
|
181
|
-
|
|
182
|
-
type: 'api-key',
|
|
183
|
-
apiKey: 'bgs_your_api_key',
|
|
184
|
-
projectId: 'your-project-uuid',
|
|
185
|
-
},
|
|
160
|
+
endpoint: 'https://api.bugspotter.com',
|
|
161
|
+
apiKey: 'bgs_your_api_key',
|
|
186
162
|
showWidget: true,
|
|
187
163
|
widgetOptions: {
|
|
188
164
|
position: 'bottom-right',
|
|
@@ -254,22 +230,84 @@ button.setBackgroundColor('#00ff00');
|
|
|
254
230
|
|
|
255
231
|
## 🔒 PII Sanitization
|
|
256
232
|
|
|
257
|
-
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 |
|
|
264
|
+
|
|
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
|
|
258
278
|
|
|
259
|
-
|
|
279
|
+
Add your own regex patterns for industry-specific data:
|
|
260
280
|
|
|
261
281
|
```javascript
|
|
262
282
|
await BugSpotter.init({
|
|
263
283
|
sanitize: {
|
|
264
|
-
enabled: true,
|
|
265
|
-
patterns:
|
|
266
|
-
customPatterns: [
|
|
267
|
-
|
|
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
|
|
268
304
|
},
|
|
269
305
|
});
|
|
270
306
|
```
|
|
271
307
|
|
|
272
|
-
|
|
308
|
+
Custom patterns produce `[REDACTED-BROKER-ACCOUNT]`, `[REDACTED-IBAN-KZ]`, etc.
|
|
309
|
+
|
|
310
|
+
**Performance:** < 50ms overhead, recursive sanitization of nested objects, supports Cyrillic text
|
|
273
311
|
|
|
274
312
|
## 📋 API Reference
|
|
275
313
|
|
|
@@ -283,43 +321,59 @@ Initialize the SDK. **This method is async** to support fetching backend-control
|
|
|
283
321
|
|
|
284
322
|
```typescript
|
|
285
323
|
interface BugSpotterConfig {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
type: 'api-key';
|
|
290
|
-
apiKey: string; // API key (bgs_...)
|
|
291
|
-
projectId: string; // Project UUID (required for file uploads)
|
|
292
|
-
};
|
|
324
|
+
apiKey: string; // Required: API key (bgs_...)
|
|
325
|
+
endpoint?: string; // Base URL of BugSpotter API
|
|
326
|
+
sampleRate?: number; // Session sampling (0-1, default: 1 = all sessions)
|
|
293
327
|
showWidget?: boolean; // Auto-show widget (default: true)
|
|
294
328
|
widgetOptions?: FloatingButtonOptions;
|
|
295
329
|
replay?: {
|
|
296
|
-
// Session replay configuration
|
|
297
330
|
enabled?: boolean; // Enable replay (default: true)
|
|
298
331
|
duration?: number; // Buffer duration in seconds (default: 15)
|
|
299
332
|
sampling?: {
|
|
300
333
|
mousemove?: number; // Mousemove throttle in ms (default: 50)
|
|
301
334
|
scroll?: number; // Scroll throttle in ms (default: 100)
|
|
302
335
|
};
|
|
336
|
+
blockSelectors?: string[]; // CSS selectors to exclude from replay
|
|
337
|
+
blockClass?: string; // CSS class to exclude from replay
|
|
303
338
|
// Quality settings (optional, backend controlled by default)
|
|
304
|
-
inlineStylesheet?: boolean;
|
|
305
|
-
inlineImages?: boolean;
|
|
306
|
-
collectFonts?: boolean;
|
|
307
|
-
recordCanvas?: boolean;
|
|
308
|
-
recordCrossOriginIframes?: boolean;
|
|
339
|
+
inlineStylesheet?: boolean;
|
|
340
|
+
inlineImages?: boolean;
|
|
341
|
+
collectFonts?: boolean;
|
|
342
|
+
recordCanvas?: boolean;
|
|
343
|
+
recordCrossOriginIframes?: boolean;
|
|
309
344
|
};
|
|
310
345
|
sanitize?: {
|
|
311
|
-
// PII sanitization configuration
|
|
312
346
|
enabled?: boolean; // Enable PII sanitization (default: true)
|
|
313
|
-
patterns?:
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
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
|
+
>;
|
|
317
369
|
customPatterns?: Array<{
|
|
318
|
-
//
|
|
319
|
-
name: string; // Pattern name for [REDACTED-NAME]
|
|
370
|
+
name: string; // Pattern name → [REDACTED-NAME]
|
|
320
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)
|
|
321
375
|
}>;
|
|
322
|
-
excludeSelectors?: string[]; // CSS selectors to exclude from sanitization
|
|
376
|
+
excludeSelectors?: string[]; // CSS selectors to exclude from DOM text sanitization (replay)
|
|
323
377
|
};
|
|
324
378
|
}
|
|
325
379
|
```
|
|
@@ -492,7 +546,6 @@ new DirectUploader(config: DirectUploadConfig)
|
|
|
492
546
|
interface DirectUploadConfig {
|
|
493
547
|
apiEndpoint: string; // Backend API URL
|
|
494
548
|
apiKey: string; // bgs_... API key
|
|
495
|
-
projectId: string; // Project UUID
|
|
496
549
|
bugId: string; // Bug report UUID
|
|
497
550
|
}
|
|
498
551
|
```
|
|
@@ -507,7 +560,9 @@ Upload screenshot directly to storage.
|
|
|
507
560
|
const screenshotBlob = await fetch(dataUrl).then((r) => r.blob());
|
|
508
561
|
|
|
509
562
|
const result = await uploader.uploadScreenshot(screenshotBlob, (progress) => {
|
|
510
|
-
console.log(
|
|
563
|
+
console.log(
|
|
564
|
+
`Screenshot: ${progress.loaded}/${progress.total} (${progress.percentage}%)`
|
|
565
|
+
);
|
|
511
566
|
});
|
|
512
567
|
|
|
513
568
|
// result: { success: true, storageKey: "screenshots/..." }
|
|
@@ -697,7 +752,7 @@ Output: `dist/bugspotter.min.js` (~99 KB)
|
|
|
697
752
|
- **Load**: < 100ms
|
|
698
753
|
- **Memory**: < 15 MB (30s replay buffer)
|
|
699
754
|
- **Screenshot**: ~500ms
|
|
700
|
-
- **PII sanitization**: <
|
|
755
|
+
- **PII sanitization**: <50ms
|
|
701
756
|
|
|
702
757
|
## 🔒 Security
|
|
703
758
|
|