@bugspotter/sdk 0.1.0-alpha.2 → 0.1.0-alpha.3
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/CHANGELOG.md +21 -0
- package/README.md +93 -62
- package/dist/bugspotter.min.js +1 -1
- package/dist/capture/network.js +5 -2
- package/dist/collectors/dom.js +2 -1
- package/dist/constants.d.ts +13 -0
- package/dist/constants.js +16 -0
- package/dist/core/file-upload-handler.d.ts +61 -0
- package/dist/core/file-upload-handler.js +157 -0
- package/dist/core/transport.d.ts +14 -25
- package/dist/core/transport.js +39 -145
- package/dist/index.d.ts +20 -2
- package/dist/index.esm.js +103 -40
- package/dist/index.js +112 -47
- package/dist/widget/button.d.ts +5 -0
- package/dist/widget/button.js +50 -12
- package/docs/SESSION_REPLAY.md +66 -4
- package/package.json +2 -2
- package/tsconfig.cjs.json +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -51,6 +51,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
51
51
|
- 345 tests (unit + E2E + Playwright)
|
|
52
52
|
- Full test coverage for core functionality
|
|
53
53
|
|
|
54
|
+
## [0.1.0-alpha.3] - 2025-11-11
|
|
55
|
+
|
|
56
|
+
### Changed
|
|
57
|
+
|
|
58
|
+
- **BREAKING**: Updated S3 upload implementation to use `fetch()` API instead of `XMLHttpRequest`
|
|
59
|
+
- More modern and efficient file upload mechanism
|
|
60
|
+
- Better compatibility with modern browser environments
|
|
61
|
+
- Improved error handling with AbortController
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- Fixed timeout memory leak in file upload handler by ensuring timeout is cleared in both success and error paths
|
|
66
|
+
- Fixed all integration and E2E tests to properly handle fetch-based S3 uploads
|
|
67
|
+
|
|
68
|
+
### Improved
|
|
69
|
+
|
|
70
|
+
- Added comprehensive JSDoc documentation for `UPLOAD_TIMEOUT_MS` constant
|
|
71
|
+
- Refactored test mocks to match actual API structure with `presignedUrls` object
|
|
72
|
+
- Centralized test fixtures to eliminate code duplication (created `test-images.ts`)
|
|
73
|
+
- All 454 SDK tests now passing with 100% pass rate
|
|
74
|
+
|
|
54
75
|
## [Unreleased]
|
|
55
76
|
|
|
56
77
|
### Planned Features
|
package/README.md
CHANGED
|
@@ -57,8 +57,12 @@ import BugSpotter from '@bugspotter/sdk';
|
|
|
57
57
|
|
|
58
58
|
// Initialize with auto-widget
|
|
59
59
|
const bugSpotter = BugSpotter.init({
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
endpoint: 'https://api.bugspotter.com/api/v1/reports',
|
|
61
|
+
auth: {
|
|
62
|
+
type: 'api-key',
|
|
63
|
+
apiKey: 'bgs_your_api_key',
|
|
64
|
+
projectId: 'your-project-uuid',
|
|
65
|
+
},
|
|
62
66
|
showWidget: true,
|
|
63
67
|
});
|
|
64
68
|
```
|
|
@@ -69,8 +73,12 @@ const bugSpotter = BugSpotter.init({
|
|
|
69
73
|
const BugSpotter = require('@bugspotter/sdk');
|
|
70
74
|
|
|
71
75
|
const bugSpotter = BugSpotter.init({
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
endpoint: 'https://api.bugspotter.com/api/v1/reports',
|
|
77
|
+
auth: {
|
|
78
|
+
type: 'api-key',
|
|
79
|
+
apiKey: 'bgs_your_api_key',
|
|
80
|
+
projectId: 'your-project-uuid',
|
|
81
|
+
},
|
|
74
82
|
showWidget: true,
|
|
75
83
|
});
|
|
76
84
|
```
|
|
@@ -82,70 +90,62 @@ const bugSpotter = BugSpotter.init({
|
|
|
82
90
|
<script>
|
|
83
91
|
// Initialize with auto-widget
|
|
84
92
|
const bugSpotter = BugSpotter.init({
|
|
85
|
-
|
|
86
|
-
|
|
93
|
+
endpoint: 'https://api.bugspotter.com/api/v1/reports',
|
|
94
|
+
auth: {
|
|
95
|
+
type: 'api-key',
|
|
96
|
+
apiKey: 'bgs_your_api_key',
|
|
97
|
+
projectId: 'your-project-uuid',
|
|
98
|
+
},
|
|
87
99
|
showWidget: true,
|
|
88
100
|
});
|
|
89
101
|
</script>
|
|
90
102
|
```
|
|
91
103
|
|
|
92
|
-
###
|
|
104
|
+
### How It Works
|
|
93
105
|
|
|
94
|
-
|
|
106
|
+
The SDK automatically uses an **optimized presigned URL upload flow** (40% fewer HTTP requests):
|
|
95
107
|
|
|
96
108
|
```javascript
|
|
97
|
-
import
|
|
98
|
-
|
|
99
|
-
// 1. Create bug report (metadata only)
|
|
100
|
-
const response = await fetch('https://api.example.com/api/v1/reports', {
|
|
101
|
-
method: 'POST',
|
|
102
|
-
headers: {
|
|
103
|
-
'Content-Type': 'application/json',
|
|
104
|
-
'x-api-key': 'bgs_your_api_key',
|
|
105
|
-
},
|
|
106
|
-
body: JSON.stringify({
|
|
107
|
-
project_id: 'project-uuid',
|
|
108
|
-
title: 'Bug title',
|
|
109
|
-
description: 'Bug description',
|
|
110
|
-
}),
|
|
111
|
-
});
|
|
112
|
-
const { id: bugId } = await response.json();
|
|
113
|
-
|
|
114
|
-
// 2. Initialize DirectUploader
|
|
115
|
-
const uploader = new DirectUploader({
|
|
116
|
-
apiEndpoint: 'https://api.example.com',
|
|
117
|
-
apiKey: 'bgs_your_api_key',
|
|
118
|
-
projectId: 'project-uuid',
|
|
119
|
-
bugId,
|
|
120
|
-
});
|
|
109
|
+
import BugSpotter from '@bugspotter/sdk';
|
|
121
110
|
|
|
122
|
-
//
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
111
|
+
// 1. Initialize SDK with required auth
|
|
112
|
+
const bugSpotter = BugSpotter.init({
|
|
113
|
+
endpoint: 'https://api.bugspotter.com/api/v1/reports',
|
|
114
|
+
auth: {
|
|
115
|
+
type: 'api-key',
|
|
116
|
+
apiKey: 'bgs_your_api_key',
|
|
117
|
+
projectId: 'your-project-uuid', // Required for file uploads
|
|
118
|
+
},
|
|
119
|
+
showWidget: true,
|
|
126
120
|
});
|
|
127
121
|
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
122
|
+
// 2. Submit a bug report (SDK handles everything automatically)
|
|
123
|
+
// Optimized flow (3 HTTP requests instead of 5):
|
|
124
|
+
// - Step 1: POST /api/v1/reports with hasScreenshot/hasReplay flags
|
|
125
|
+
// → Returns bug ID + presigned URLs for screenshot & replay
|
|
126
|
+
// - Step 2: PUT to S3 presigned URLs (parallel uploads)
|
|
127
|
+
// - Step 3: POST /api/v1/reports/{id}/confirm-upload (confirm each file)
|
|
133
128
|
```
|
|
134
129
|
|
|
135
130
|
**Benefits:**
|
|
136
131
|
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
-
|
|
132
|
+
- **40% fewer HTTP requests** - 3 requests vs 5 in legacy flow
|
|
133
|
+
- Files upload directly to S3 (faster, no API bottleneck)
|
|
134
|
+
- Automatic compression for replay events
|
|
135
|
+
- Concurrent uploads (screenshot + replay in parallel)
|
|
136
|
+
- Reduced server load
|
|
141
137
|
|
|
142
138
|
### Manual Capture
|
|
143
139
|
|
|
144
140
|
```javascript
|
|
145
141
|
// Initialize without widget
|
|
146
142
|
const bugSpotter = BugSpotter.init({
|
|
147
|
-
|
|
148
|
-
|
|
143
|
+
endpoint: 'https://api.bugspotter.com/api/v1/reports',
|
|
144
|
+
auth: {
|
|
145
|
+
type: 'api-key',
|
|
146
|
+
apiKey: 'bgs_your_api_key',
|
|
147
|
+
projectId: 'your-project-uuid',
|
|
148
|
+
},
|
|
149
149
|
showWidget: false,
|
|
150
150
|
});
|
|
151
151
|
|
|
@@ -164,8 +164,12 @@ async function reportBug() {
|
|
|
164
164
|
```javascript
|
|
165
165
|
// Widget appears automatically with showWidget: true
|
|
166
166
|
const bugSpotter = BugSpotter.init({
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
endpoint: 'https://api.bugspotter.com/api/v1/reports',
|
|
168
|
+
auth: {
|
|
169
|
+
type: 'api-key',
|
|
170
|
+
apiKey: 'bgs_your_api_key',
|
|
171
|
+
projectId: 'your-project-uuid',
|
|
172
|
+
},
|
|
169
173
|
showWidget: true,
|
|
170
174
|
widgetOptions: {
|
|
171
175
|
position: 'bottom-right',
|
|
@@ -179,17 +183,35 @@ const bugSpotter = BugSpotter.init({
|
|
|
179
183
|
### Custom Widget
|
|
180
184
|
|
|
181
185
|
```javascript
|
|
182
|
-
//
|
|
186
|
+
// Default professional SVG icon (recommended)
|
|
183
187
|
const button = new BugSpotter.FloatingButton({
|
|
188
|
+
position: 'bottom-right',
|
|
189
|
+
// icon: 'svg' is default - professional bug icon
|
|
190
|
+
backgroundColor: '#2563eb', // Professional blue (default)
|
|
191
|
+
tooltip: 'Report an Issue',
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// Custom emoji/text icon
|
|
195
|
+
const button2 = new BugSpotter.FloatingButton({
|
|
184
196
|
position: 'bottom-right',
|
|
185
197
|
icon: '🐛',
|
|
186
198
|
backgroundColor: '#ff4444',
|
|
187
199
|
size: 56,
|
|
188
200
|
offset: { x: 24, y: 24 },
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Custom SVG icon
|
|
204
|
+
const button3 = new BugSpotter.FloatingButton({
|
|
205
|
+
position: 'bottom-left',
|
|
206
|
+
customSvg: `
|
|
207
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
208
|
+
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
|
|
209
|
+
<path d="M2 17l10 5 10-5M2 12l10 5 10-5"/>
|
|
210
|
+
</svg>
|
|
211
|
+
`,
|
|
212
|
+
tooltip: 'Custom Report Button',
|
|
213
|
+
backgroundColor: '#1a365d',
|
|
214
|
+
size: 48,
|
|
193
215
|
});
|
|
194
216
|
|
|
195
217
|
// Handle click
|
|
@@ -217,7 +239,7 @@ button.onClick(async () => {
|
|
|
217
239
|
},
|
|
218
240
|
});
|
|
219
241
|
|
|
220
|
-
modal.show(report.
|
|
242
|
+
modal.show(report._screenshotPreview || '');
|
|
221
243
|
});
|
|
222
244
|
|
|
223
245
|
// Control button
|
|
@@ -258,8 +280,13 @@ Initialize the SDK.
|
|
|
258
280
|
|
|
259
281
|
```typescript
|
|
260
282
|
interface BugSpotterConfig {
|
|
261
|
-
|
|
262
|
-
|
|
283
|
+
endpoint: string; // Required: Backend API URL
|
|
284
|
+
auth: {
|
|
285
|
+
// Required: Authentication configuration
|
|
286
|
+
type: 'api-key';
|
|
287
|
+
apiKey: string; // API key (bgs_...)
|
|
288
|
+
projectId: string; // Project UUID (required for file uploads)
|
|
289
|
+
};
|
|
263
290
|
showWidget?: boolean; // Auto-show widget (default: true)
|
|
264
291
|
widgetOptions?: FloatingButtonOptions;
|
|
265
292
|
replay?: {
|
|
@@ -298,11 +325,13 @@ Capture current bug report data.
|
|
|
298
325
|
|
|
299
326
|
```typescript
|
|
300
327
|
interface BugReport {
|
|
301
|
-
|
|
328
|
+
screenshotKey?: string; // Storage key after presigned URL upload
|
|
302
329
|
console: ConsoleLog[]; // Array of console entries
|
|
303
330
|
network: NetworkRequest[]; // Array of network requests
|
|
304
331
|
metadata: BrowserMetadata; // Browser/system info
|
|
305
|
-
replay
|
|
332
|
+
replay?: eventWithTime[]; // Session replay events (rrweb format)
|
|
333
|
+
replayKey?: string; // Storage key after presigned URL upload
|
|
334
|
+
_screenshotPreview?: string; // Internal: screenshot preview for modal (not sent to API)
|
|
306
335
|
}
|
|
307
336
|
|
|
308
337
|
interface ConsoleLog {
|
|
@@ -350,10 +379,12 @@ new FloatingButton(options?: FloatingButtonOptions)
|
|
|
350
379
|
|
|
351
380
|
interface FloatingButtonOptions {
|
|
352
381
|
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
|
|
353
|
-
icon?: string; //
|
|
354
|
-
|
|
355
|
-
|
|
382
|
+
icon?: string; // 'svg' for default bug icon, or custom emoji/text
|
|
383
|
+
customSvg?: string; // Custom SVG icon (overrides icon if provided)
|
|
384
|
+
backgroundColor?: string; // CSS color (default: '#2563eb' professional blue)
|
|
385
|
+
size?: number; // Size in pixels (default: 56)
|
|
356
386
|
offset?: { x: number; y: number };
|
|
387
|
+
tooltip?: string; // Custom tooltip text (default: 'Report an Issue')
|
|
357
388
|
style?: Record<string, string>; // Additional CSS
|
|
358
389
|
}
|
|
359
390
|
```
|