bugcatch-sdk 0.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/README.md ADDED
@@ -0,0 +1,233 @@
1
+ # bugcatch-sdk
2
+
3
+ Official JavaScript/TypeScript SDK for [BugCatch](https://github.com/your-org/bugcatch) — lightweight error tracking for web and Node.js applications.
4
+
5
+ ## Features
6
+
7
+ - Automatic capture of uncaught errors and unhandled promise rejections
8
+ - Manual `captureException` and `captureMessage` APIs
9
+ - Breadcrumb trail: clicks, navigation, console calls
10
+ - User context and custom tags
11
+ - `beforeSend` hook to filter or modify events before sending
12
+ - Works in the browser (modern bundlers + CDN) and Node.js
13
+ - Zero runtime dependencies — ~15 KB minified
14
+
15
+ ---
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install bugcatch-sdk
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Quick Start
26
+
27
+ ```typescript
28
+ import BugCatch from 'bugcatch-sdk';
29
+
30
+ BugCatch.init({
31
+ dsn: 'http://localhost:3000/ingest/<projectId>?key=<sdkKey>',
32
+ release: '1.0.0',
33
+ environment: 'production',
34
+ });
35
+ ```
36
+
37
+ The DSN is available on your project page in the BugCatch dashboard.
38
+
39
+ From this point on, all uncaught errors and unhandled promise rejections are captured automatically.
40
+
41
+ ---
42
+
43
+ ## Manual Captures
44
+
45
+ ```typescript
46
+ // Capture an Error object
47
+ try {
48
+ await processOrder(order);
49
+ } catch (err) {
50
+ BugCatch.captureException(err, { orderId: order.id });
51
+ }
52
+
53
+ // Capture a plain message
54
+ BugCatch.captureMessage('Quota limit reached', 'warning', { used: 95 });
55
+ ```
56
+
57
+ ---
58
+
59
+ ## User Context
60
+
61
+ ```typescript
62
+ // After login
63
+ BugCatch.setUser({ id: '42', email: 'jane@example.com', username: 'jane' });
64
+
65
+ // After logout
66
+ BugCatch.clearUser();
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Tags
72
+
73
+ ```typescript
74
+ BugCatch.setTag('plan', 'pro');
75
+ BugCatch.setTag('region', 'eu-west-1');
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Options
81
+
82
+ ```typescript
83
+ BugCatch.init({
84
+ // Required
85
+ dsn: string;
86
+
87
+ // Optional
88
+ release?: string; // App version e.g. "1.2.3"
89
+ environment?: string; // "production" | "staging" | ...
90
+ debug?: boolean; // Print SDK logs to console (default: false)
91
+ maxBreadcrumbs?: number; // Max breadcrumbs kept in memory (default: 100)
92
+ autoCaptureErrors?: boolean; // Auto-attach global error handlers (default: true)
93
+ autoCaptureBreadcrumbs?: boolean; // Auto-capture clicks, nav, console (default: true)
94
+
95
+ // Drop errors whose message matches any of these
96
+ ignoreErrors?: Array<string | RegExp>;
97
+
98
+ // Drop errors originating from matching script URLs
99
+ ignoreUrls?: Array<string | RegExp>;
100
+
101
+ // Modify or drop an event before it is sent. Return false to discard.
102
+ beforeSend?: (event: EventPayload) => EventPayload | false;
103
+ });
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Framework Examples
109
+
110
+ ### React
111
+
112
+ ```tsx
113
+ // src/main.tsx
114
+ import BugCatch from 'bugcatch-sdk';
115
+
116
+ BugCatch.init({
117
+ dsn: import.meta.env.VITE_BUGCATCH_DSN,
118
+ release: import.meta.env.VITE_APP_VERSION,
119
+ environment: import.meta.env.MODE,
120
+ });
121
+ ```
122
+
123
+ **Error boundary:**
124
+
125
+ ```tsx
126
+ class ErrorBoundary extends React.Component {
127
+ componentDidCatch(error: Error) {
128
+ BugCatch.captureException(error);
129
+ }
130
+ render() {
131
+ return this.props.children;
132
+ }
133
+ }
134
+ ```
135
+
136
+ ### Vue
137
+
138
+ ```ts
139
+ // src/main.ts
140
+ import BugCatch from 'bugcatch-sdk';
141
+
142
+ BugCatch.init({ dsn: import.meta.env.VITE_BUGCATCH_DSN });
143
+
144
+ app.config.errorHandler = (err) => {
145
+ BugCatch.captureException(err);
146
+ };
147
+ ```
148
+
149
+ ### Node.js / Express
150
+
151
+ ```typescript
152
+ import BugCatch from 'bugcatch-sdk';
153
+
154
+ BugCatch.init({
155
+ dsn: process.env.BUGCATCH_DSN!,
156
+ release: process.env.npm_package_version,
157
+ environment: process.env.NODE_ENV,
158
+ autoCaptureBreadcrumbs: false, // no DOM in Node.js
159
+ });
160
+
161
+ // Error middleware
162
+ app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
163
+ BugCatch.captureException(err, { path: req.path, method: req.method });
164
+ next(err);
165
+ });
166
+ ```
167
+
168
+ ### CommonJS
169
+
170
+ ```javascript
171
+ const { BugCatch } = require('bugcatch-sdk');
172
+
173
+ BugCatch.init({ dsn: process.env.BUGCATCH_DSN });
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Breadcrumbs
179
+
180
+ Breadcrumbs are short records of what happened before an error. The SDK captures them automatically when `autoCaptureBreadcrumbs: true` (default):
181
+
182
+ | Source | Category | What is recorded |
183
+ |--------|----------|-----------------|
184
+ | DOM clicks | `ui.click` | Element tag, text, id/class |
185
+ | History navigation | `navigation` | URL navigated to |
186
+ | `console.warn` / `console.error` | `console` | Message text |
187
+
188
+ Add breadcrumbs manually:
189
+
190
+ ```typescript
191
+ BugCatch.addBreadcrumb({
192
+ timestamp: new Date().toISOString(),
193
+ type: 'user',
194
+ category: 'auth',
195
+ message: 'User logged in',
196
+ data: { method: 'google-oauth' },
197
+ });
198
+ ```
199
+
200
+ ---
201
+
202
+ ## beforeSend
203
+
204
+ Use `beforeSend` to scrub sensitive data or drop specific events:
205
+
206
+ ```typescript
207
+ BugCatch.init({
208
+ dsn: '...',
209
+ beforeSend(event) {
210
+ // Drop network errors
211
+ if (event.exception?.values?.[0]?.type === 'NetworkError') return false;
212
+
213
+ // Scrub email from user context
214
+ if (event.user) delete event.user.email;
215
+
216
+ return event;
217
+ },
218
+ });
219
+ ```
220
+
221
+ ---
222
+
223
+ ## SPA / Hot-Reload Cleanup
224
+
225
+ ```typescript
226
+ BugCatch.destroy(); // removes all listeners, resets singleton
227
+ ```
228
+
229
+ ---
230
+
231
+ ## License
232
+
233
+ ISC
@@ -0,0 +1,159 @@
1
+ interface BugCatchOptions {
2
+ /** DSN from the BugCatch dashboard. Format: http://host/ingest/{projectId}?key={sdkKey} */
3
+ dsn: string;
4
+ /** Application release version, e.g. "1.2.3". Attached to every event. */
5
+ release?: string;
6
+ /** Deployment environment, e.g. "production" | "staging". Attached to every event. */
7
+ environment?: string;
8
+ /** Print debug info to the console. Default: false. */
9
+ debug?: boolean;
10
+ /** Max breadcrumbs to keep in memory. Default: 100. */
11
+ maxBreadcrumbs?: number;
12
+ /**
13
+ * Automatically attach global error handlers and capture breadcrumbs.
14
+ * Default: true. Set to false to manage captures manually.
15
+ */
16
+ autoCaptureErrors?: boolean;
17
+ /**
18
+ * Automatically capture breadcrumbs from clicks, navigation, and console.
19
+ * Default: true.
20
+ */
21
+ autoCaptureBreadcrumbs?: boolean;
22
+ /**
23
+ * A list of URL patterns (strings or RegExps). Any error originating from
24
+ * a script URL that matches will be ignored.
25
+ */
26
+ ignoreUrls?: Array<string | RegExp>;
27
+ /**
28
+ * A list of error message patterns (strings or RegExps). Matching errors
29
+ * will be dropped before being sent.
30
+ */
31
+ ignoreErrors?: Array<string | RegExp>;
32
+ /** Called before an event is sent. Return false to drop the event. */
33
+ beforeSend?: (event: EventPayload) => EventPayload | false;
34
+ }
35
+ interface UserContext {
36
+ id?: string;
37
+ email?: string;
38
+ username?: string;
39
+ }
40
+ interface BreadcrumbEntry {
41
+ timestamp: string;
42
+ type?: string;
43
+ category?: string;
44
+ message?: string;
45
+ data?: Record<string, unknown>;
46
+ }
47
+ interface StackFrame {
48
+ filename?: string;
49
+ lineno?: number;
50
+ colno?: number;
51
+ function?: string;
52
+ context_line?: string;
53
+ in_app?: boolean;
54
+ }
55
+ interface ExceptionValue {
56
+ type?: string;
57
+ value?: string;
58
+ stacktrace?: {
59
+ frames: StackFrame[];
60
+ };
61
+ }
62
+ interface EventPayload {
63
+ event_id: string;
64
+ timestamp: string;
65
+ level?: string;
66
+ message?: string;
67
+ platform: string;
68
+ release?: string;
69
+ environment?: string;
70
+ user?: UserContext;
71
+ request?: {
72
+ url?: string;
73
+ method?: string;
74
+ headers?: Record<string, string>;
75
+ };
76
+ exception?: {
77
+ values: ExceptionValue[];
78
+ };
79
+ breadcrumbs?: BreadcrumbEntry[];
80
+ tags?: Record<string, string>;
81
+ extra?: Record<string, unknown>;
82
+ }
83
+ interface ParsedDsn {
84
+ /** Full URL including path and query, e.g. http://host/ingest/projectId?key=xyz */
85
+ ingestUrl: string;
86
+ projectId: string;
87
+ sdkKey: string;
88
+ }
89
+
90
+ declare class BugCatchClient {
91
+ private readonly opts;
92
+ private readonly dsn;
93
+ private readonly crumbs;
94
+ private user;
95
+ private tags;
96
+ private readonly cleanups;
97
+ constructor(options: BugCatchOptions);
98
+ captureException(error: unknown, extra?: Record<string, unknown>): string;
99
+ captureMessage(message: string, level?: string, extra?: Record<string, unknown>): string;
100
+ setUser(user: UserContext): void;
101
+ clearUser(): void;
102
+ setTag(key: string, value: string): void;
103
+ addBreadcrumb(crumb: BreadcrumbEntry): void;
104
+ /** Tear down all global listeners. Call when unmounting in SPAs. */
105
+ destroy(): void;
106
+ private buildExceptionPayload;
107
+ private buildMessagePayload;
108
+ private buildBase;
109
+ private installErrorHandlers;
110
+ private shouldIgnore;
111
+ private send;
112
+ private log;
113
+ }
114
+
115
+ declare const BugCatch: {
116
+ /**
117
+ * Initialize the SDK. Call this once, as early as possible in your app.
118
+ *
119
+ * @example
120
+ * BugCatch.init({
121
+ * dsn: 'http://localhost:3000/ingest/project-id?key=sdk-key',
122
+ * release: '1.0.0',
123
+ * environment: 'production',
124
+ * });
125
+ */
126
+ init(options: BugCatchOptions): BugCatchClient;
127
+ /**
128
+ * Capture an Error object or any value as an error event.
129
+ * Returns the generated event_id.
130
+ */
131
+ captureException(error: unknown, extra?: Record<string, unknown>): string;
132
+ /**
133
+ * Capture a plain text message as an event.
134
+ * Returns the generated event_id.
135
+ */
136
+ captureMessage(message: string, level?: string, extra?: Record<string, unknown>): string;
137
+ /**
138
+ * Set the current user context. Attached to all subsequent events.
139
+ */
140
+ setUser(user: UserContext): void;
141
+ /**
142
+ * Clear the current user context (e.g. on logout).
143
+ */
144
+ clearUser(): void;
145
+ /**
146
+ * Set a tag that will be attached to all subsequent events.
147
+ */
148
+ setTag(key: string, value: string): void;
149
+ /**
150
+ * Manually add a breadcrumb.
151
+ */
152
+ addBreadcrumb(crumb: BreadcrumbEntry): void;
153
+ /**
154
+ * Tear down all listeners. Useful in SPA cleanup or hot-reload scenarios.
155
+ */
156
+ destroy(): void;
157
+ };
158
+
159
+ export { type BreadcrumbEntry, BugCatch, BugCatchClient, type BugCatchOptions, type EventPayload, type ParsedDsn, type StackFrame, type UserContext, BugCatch as default };
@@ -0,0 +1,159 @@
1
+ interface BugCatchOptions {
2
+ /** DSN from the BugCatch dashboard. Format: http://host/ingest/{projectId}?key={sdkKey} */
3
+ dsn: string;
4
+ /** Application release version, e.g. "1.2.3". Attached to every event. */
5
+ release?: string;
6
+ /** Deployment environment, e.g. "production" | "staging". Attached to every event. */
7
+ environment?: string;
8
+ /** Print debug info to the console. Default: false. */
9
+ debug?: boolean;
10
+ /** Max breadcrumbs to keep in memory. Default: 100. */
11
+ maxBreadcrumbs?: number;
12
+ /**
13
+ * Automatically attach global error handlers and capture breadcrumbs.
14
+ * Default: true. Set to false to manage captures manually.
15
+ */
16
+ autoCaptureErrors?: boolean;
17
+ /**
18
+ * Automatically capture breadcrumbs from clicks, navigation, and console.
19
+ * Default: true.
20
+ */
21
+ autoCaptureBreadcrumbs?: boolean;
22
+ /**
23
+ * A list of URL patterns (strings or RegExps). Any error originating from
24
+ * a script URL that matches will be ignored.
25
+ */
26
+ ignoreUrls?: Array<string | RegExp>;
27
+ /**
28
+ * A list of error message patterns (strings or RegExps). Matching errors
29
+ * will be dropped before being sent.
30
+ */
31
+ ignoreErrors?: Array<string | RegExp>;
32
+ /** Called before an event is sent. Return false to drop the event. */
33
+ beforeSend?: (event: EventPayload) => EventPayload | false;
34
+ }
35
+ interface UserContext {
36
+ id?: string;
37
+ email?: string;
38
+ username?: string;
39
+ }
40
+ interface BreadcrumbEntry {
41
+ timestamp: string;
42
+ type?: string;
43
+ category?: string;
44
+ message?: string;
45
+ data?: Record<string, unknown>;
46
+ }
47
+ interface StackFrame {
48
+ filename?: string;
49
+ lineno?: number;
50
+ colno?: number;
51
+ function?: string;
52
+ context_line?: string;
53
+ in_app?: boolean;
54
+ }
55
+ interface ExceptionValue {
56
+ type?: string;
57
+ value?: string;
58
+ stacktrace?: {
59
+ frames: StackFrame[];
60
+ };
61
+ }
62
+ interface EventPayload {
63
+ event_id: string;
64
+ timestamp: string;
65
+ level?: string;
66
+ message?: string;
67
+ platform: string;
68
+ release?: string;
69
+ environment?: string;
70
+ user?: UserContext;
71
+ request?: {
72
+ url?: string;
73
+ method?: string;
74
+ headers?: Record<string, string>;
75
+ };
76
+ exception?: {
77
+ values: ExceptionValue[];
78
+ };
79
+ breadcrumbs?: BreadcrumbEntry[];
80
+ tags?: Record<string, string>;
81
+ extra?: Record<string, unknown>;
82
+ }
83
+ interface ParsedDsn {
84
+ /** Full URL including path and query, e.g. http://host/ingest/projectId?key=xyz */
85
+ ingestUrl: string;
86
+ projectId: string;
87
+ sdkKey: string;
88
+ }
89
+
90
+ declare class BugCatchClient {
91
+ private readonly opts;
92
+ private readonly dsn;
93
+ private readonly crumbs;
94
+ private user;
95
+ private tags;
96
+ private readonly cleanups;
97
+ constructor(options: BugCatchOptions);
98
+ captureException(error: unknown, extra?: Record<string, unknown>): string;
99
+ captureMessage(message: string, level?: string, extra?: Record<string, unknown>): string;
100
+ setUser(user: UserContext): void;
101
+ clearUser(): void;
102
+ setTag(key: string, value: string): void;
103
+ addBreadcrumb(crumb: BreadcrumbEntry): void;
104
+ /** Tear down all global listeners. Call when unmounting in SPAs. */
105
+ destroy(): void;
106
+ private buildExceptionPayload;
107
+ private buildMessagePayload;
108
+ private buildBase;
109
+ private installErrorHandlers;
110
+ private shouldIgnore;
111
+ private send;
112
+ private log;
113
+ }
114
+
115
+ declare const BugCatch: {
116
+ /**
117
+ * Initialize the SDK. Call this once, as early as possible in your app.
118
+ *
119
+ * @example
120
+ * BugCatch.init({
121
+ * dsn: 'http://localhost:3000/ingest/project-id?key=sdk-key',
122
+ * release: '1.0.0',
123
+ * environment: 'production',
124
+ * });
125
+ */
126
+ init(options: BugCatchOptions): BugCatchClient;
127
+ /**
128
+ * Capture an Error object or any value as an error event.
129
+ * Returns the generated event_id.
130
+ */
131
+ captureException(error: unknown, extra?: Record<string, unknown>): string;
132
+ /**
133
+ * Capture a plain text message as an event.
134
+ * Returns the generated event_id.
135
+ */
136
+ captureMessage(message: string, level?: string, extra?: Record<string, unknown>): string;
137
+ /**
138
+ * Set the current user context. Attached to all subsequent events.
139
+ */
140
+ setUser(user: UserContext): void;
141
+ /**
142
+ * Clear the current user context (e.g. on logout).
143
+ */
144
+ clearUser(): void;
145
+ /**
146
+ * Set a tag that will be attached to all subsequent events.
147
+ */
148
+ setTag(key: string, value: string): void;
149
+ /**
150
+ * Manually add a breadcrumb.
151
+ */
152
+ addBreadcrumb(crumb: BreadcrumbEntry): void;
153
+ /**
154
+ * Tear down all listeners. Useful in SPA cleanup or hot-reload scenarios.
155
+ */
156
+ destroy(): void;
157
+ };
158
+
159
+ export { type BreadcrumbEntry, BugCatch, BugCatchClient, type BugCatchOptions, type EventPayload, type ParsedDsn, type StackFrame, type UserContext, BugCatch as default };