@arvoretech/bug-jar 0.3.1 → 0.4.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/README.md +48 -29
- package/dist/index.d.mts +15 -7
- package/dist/index.d.ts +15 -7
- package/dist/index.global.js +38 -279
- package/dist/index.js +37 -278
- package/dist/index.mjs +38 -279
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# 🪲 Bug Jar
|
|
2
2
|
|
|
3
|
-
Capture everything for non-technical people to help debug. One
|
|
3
|
+
Capture everything for non-technical people to help debug. One debug link, zero config.
|
|
4
4
|
|
|
5
|
-
Bug Jar is a lightweight JavaScript library that silently records all browser activity (network requests, console logs, errors, user actions, performance metrics, and more) and lets
|
|
5
|
+
Bug Jar is a lightweight JavaScript library that silently records all browser activity (network requests, console logs, errors, user actions, performance metrics, and more) and lets you capture a complete, encrypted debug session from a one-time debug link.
|
|
6
6
|
|
|
7
7
|
## Why?
|
|
8
8
|
|
|
9
|
-
Because asking someone to "open DevTools and check the Network tab" doesn't scale. Bug Jar gives your support team
|
|
9
|
+
Because asking someone to "open DevTools and check the Network tab" doesn't scale. Bug Jar gives your support team and QA a link they can send to anyone to capture everything developers need to reproduce and fix bugs.
|
|
10
10
|
|
|
11
11
|
## What it captures
|
|
12
12
|
|
|
@@ -26,30 +26,19 @@ Because asking someone to "open DevTools and check the Network tab" doesn't scal
|
|
|
26
26
|
|
|
27
27
|
## Quick Start
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Bug Jar runs as a **debug session**: staff generates a one-time link, the user
|
|
30
|
+
opens it in the real app, and the encrypted package is uploaded to S3. See
|
|
31
|
+
[Debug Session Mode](#debug-session-mode-encrypted-upload-to-s3) below.
|
|
30
32
|
|
|
31
33
|
```html
|
|
32
34
|
<script src="https://unpkg.com/@arvoretech/bug-jar"></script>
|
|
33
35
|
<script>
|
|
34
|
-
BugJar.init(
|
|
36
|
+
BugJar.init({
|
|
37
|
+
debugSessionEndpoint: 'https://api.arvore.com.br/debug-sessions',
|
|
38
|
+
})
|
|
35
39
|
</script>
|
|
36
40
|
```
|
|
37
41
|
|
|
38
|
-
### NPM
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
npm install @arvoretech/bug-jar
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
```typescript
|
|
45
|
-
import { init } from '@arvoretech/bug-jar'
|
|
46
|
-
|
|
47
|
-
init({
|
|
48
|
-
endpoint: 'https://your-api.com/bug-reports',
|
|
49
|
-
uiPosition: 'bottom-right',
|
|
50
|
-
})
|
|
51
|
-
```
|
|
52
|
-
|
|
53
42
|
## Configuration
|
|
54
43
|
|
|
55
44
|
```typescript
|
|
@@ -74,16 +63,12 @@ init({
|
|
|
74
63
|
// Privacy — fields containing these strings are redacted
|
|
75
64
|
sensitiveFields: ['password', 'token', 'secret', 'authorization', 'cookie', 'session', 'credit_card', 'cvv', 'ssn', 'cpf'],
|
|
76
65
|
|
|
77
|
-
// Where to send reports (if not set, downloads as JSON file)
|
|
78
|
-
endpoint: 'https://your-api.com/bug-reports',
|
|
79
|
-
|
|
80
66
|
// Callback when report is generated
|
|
81
67
|
onCapture: (report) => console.log(report),
|
|
82
68
|
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
uiLabel: 'Reportar Bug',
|
|
69
|
+
// Debug session
|
|
70
|
+
debugSessionEndpoint: 'https://api.arvore.com.br/debug-sessions',
|
|
71
|
+
// debugToken is read automatically from the ?debug=<token> query param
|
|
87
72
|
})
|
|
88
73
|
```
|
|
89
74
|
|
|
@@ -92,7 +77,7 @@ init({
|
|
|
92
77
|
```typescript
|
|
93
78
|
import { BugJar } from '@arvoretech/bug-jar'
|
|
94
79
|
|
|
95
|
-
const jar = new BugJar(
|
|
80
|
+
const jar = new BugJar()
|
|
96
81
|
jar.start()
|
|
97
82
|
|
|
98
83
|
// Later, capture a report programmatically
|
|
@@ -105,12 +90,46 @@ await fetch('/api/bugs', {
|
|
|
105
90
|
})
|
|
106
91
|
```
|
|
107
92
|
|
|
93
|
+
## Debug Session Mode (encrypted upload to S3)
|
|
94
|
+
|
|
95
|
+
For non-technical users, staff can generate a one-time debug link. The user opens
|
|
96
|
+
the link in the real app, reproduces the bug, and Bug Jar records the whole flow,
|
|
97
|
+
encrypts the package end-to-end in the browser, and uploads it straight to a
|
|
98
|
+
private S3 bucket via a presigned URL. No AWS credentials ever reach the browser.
|
|
99
|
+
|
|
100
|
+
```html
|
|
101
|
+
<script src="https://unpkg.com/@arvoretech/bug-jar"></script>
|
|
102
|
+
<script>
|
|
103
|
+
BugJar.init({
|
|
104
|
+
debugSessionEndpoint: 'https://api.arvore.com.br/debug-sessions',
|
|
105
|
+
// debugToken is read automatically from the ?debug=<token> query param
|
|
106
|
+
})
|
|
107
|
+
</script>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Flow:
|
|
111
|
+
|
|
112
|
+
1. Staff (admin) calls `POST /debug-sessions` with the target app URL and gets back
|
|
113
|
+
a `debugLink` (`https://app.../?debug=<token>`), the presigned PUT URL, the
|
|
114
|
+
server public key, and an expiry.
|
|
115
|
+
2. The user opens the link. Bug Jar detects `?debug=<token>`, fetches the session
|
|
116
|
+
from `debugSessionEndpoint`, starts screen recording, and shows a top banner.
|
|
117
|
+
3. The user clicks **Finalizar e enviar**. Bug Jar builds the ZIP, encrypts it
|
|
118
|
+
(libsodium sealed box + secretbox hybrid), and uploads the encrypted blob to S3.
|
|
119
|
+
4. Staff downloads the `.bin` via `GET /debug-sessions/:token/download` and
|
|
120
|
+
decrypts it offline with the private key.
|
|
121
|
+
|
|
122
|
+
The package leaves the browser already unreadable; only the holder of the X25519
|
|
123
|
+
private key can open it. `libsodium-wrappers` is loaded dynamically, so it only
|
|
124
|
+
ships when debug mode is actually used.
|
|
125
|
+
|
|
126
|
+
|
|
108
127
|
## Privacy & Security
|
|
109
128
|
|
|
110
129
|
- Sensitive fields are automatically redacted (passwords, tokens, secrets, etc.)
|
|
111
130
|
- Password inputs are never captured
|
|
112
131
|
- You control what gets captured via configuration
|
|
113
|
-
- No data leaves the browser unless
|
|
132
|
+
- No data leaves the browser unless a debug session is active
|
|
114
133
|
- All processing happens client-side
|
|
115
134
|
|
|
116
135
|
## Browser Support
|
package/dist/index.d.mts
CHANGED
|
@@ -15,11 +15,8 @@ interface BugJarConfig {
|
|
|
15
15
|
sensitiveFields: string[];
|
|
16
16
|
endpoint?: string;
|
|
17
17
|
onCapture?: (report: BugReport) => void;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
uiLabel: string;
|
|
21
|
-
hideOnMobile?: boolean;
|
|
22
|
-
uiCompactOnMobile?: boolean;
|
|
18
|
+
debugToken?: string;
|
|
19
|
+
debugSessionEndpoint?: string;
|
|
23
20
|
}
|
|
24
21
|
interface NetworkEntry {
|
|
25
22
|
id: string;
|
|
@@ -136,6 +133,14 @@ declare function generateSummary(report: BugReport): string;
|
|
|
136
133
|
|
|
137
134
|
declare function exportAsZip(report: BugReport, videoBlob: Blob | null): Promise<Blob>;
|
|
138
135
|
|
|
136
|
+
interface DebugSessionPayload {
|
|
137
|
+
token: string;
|
|
138
|
+
publicKey: string;
|
|
139
|
+
presignedPut: string;
|
|
140
|
+
reportId: string;
|
|
141
|
+
expiresAt: number;
|
|
142
|
+
}
|
|
143
|
+
|
|
139
144
|
declare class BugJar {
|
|
140
145
|
private config;
|
|
141
146
|
private network;
|
|
@@ -148,7 +153,8 @@ declare class BugJar {
|
|
|
148
153
|
private screenshot;
|
|
149
154
|
private featureFlags;
|
|
150
155
|
private screenRecorder;
|
|
151
|
-
private
|
|
156
|
+
private debugBanner;
|
|
157
|
+
private debugSession;
|
|
152
158
|
private started;
|
|
153
159
|
constructor(config?: Partial<BugJarConfig>);
|
|
154
160
|
start(): void;
|
|
@@ -158,7 +164,9 @@ declare class BugJar {
|
|
|
158
164
|
capture(userDescription?: string): Promise<BugReport>;
|
|
159
165
|
captureAndExport(userDescription?: string): Promise<BugReport>;
|
|
160
166
|
getReport(): Promise<BugReport>;
|
|
167
|
+
private startDebugSession;
|
|
168
|
+
private finishDebugSession;
|
|
161
169
|
}
|
|
162
170
|
declare function init(config?: Partial<BugJarConfig>): BugJar;
|
|
163
171
|
|
|
164
|
-
export { BugJar, type BugJarConfig, type BugReport, BugJar as default, exportAsZip, generateSummary, init };
|
|
172
|
+
export { BugJar, type BugJarConfig, type BugReport, type DebugSessionPayload, BugJar as default, exportAsZip, generateSummary, init };
|
package/dist/index.d.ts
CHANGED
|
@@ -15,11 +15,8 @@ interface BugJarConfig {
|
|
|
15
15
|
sensitiveFields: string[];
|
|
16
16
|
endpoint?: string;
|
|
17
17
|
onCapture?: (report: BugReport) => void;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
uiLabel: string;
|
|
21
|
-
hideOnMobile?: boolean;
|
|
22
|
-
uiCompactOnMobile?: boolean;
|
|
18
|
+
debugToken?: string;
|
|
19
|
+
debugSessionEndpoint?: string;
|
|
23
20
|
}
|
|
24
21
|
interface NetworkEntry {
|
|
25
22
|
id: string;
|
|
@@ -136,6 +133,14 @@ declare function generateSummary(report: BugReport): string;
|
|
|
136
133
|
|
|
137
134
|
declare function exportAsZip(report: BugReport, videoBlob: Blob | null): Promise<Blob>;
|
|
138
135
|
|
|
136
|
+
interface DebugSessionPayload {
|
|
137
|
+
token: string;
|
|
138
|
+
publicKey: string;
|
|
139
|
+
presignedPut: string;
|
|
140
|
+
reportId: string;
|
|
141
|
+
expiresAt: number;
|
|
142
|
+
}
|
|
143
|
+
|
|
139
144
|
declare class BugJar {
|
|
140
145
|
private config;
|
|
141
146
|
private network;
|
|
@@ -148,7 +153,8 @@ declare class BugJar {
|
|
|
148
153
|
private screenshot;
|
|
149
154
|
private featureFlags;
|
|
150
155
|
private screenRecorder;
|
|
151
|
-
private
|
|
156
|
+
private debugBanner;
|
|
157
|
+
private debugSession;
|
|
152
158
|
private started;
|
|
153
159
|
constructor(config?: Partial<BugJarConfig>);
|
|
154
160
|
start(): void;
|
|
@@ -158,7 +164,9 @@ declare class BugJar {
|
|
|
158
164
|
capture(userDescription?: string): Promise<BugReport>;
|
|
159
165
|
captureAndExport(userDescription?: string): Promise<BugReport>;
|
|
160
166
|
getReport(): Promise<BugReport>;
|
|
167
|
+
private startDebugSession;
|
|
168
|
+
private finishDebugSession;
|
|
161
169
|
}
|
|
162
170
|
declare function init(config?: Partial<BugJarConfig>): BugJar;
|
|
163
171
|
|
|
164
|
-
export { BugJar, type BugJarConfig, type BugReport, BugJar as default, exportAsZip, generateSummary, init };
|
|
172
|
+
export { BugJar, type BugJarConfig, type BugReport, type DebugSessionPayload, BugJar as default, exportAsZip, generateSummary, init };
|