@bugwatch/core 0.1.0 → 0.2.1
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/dist/index.d.mts +237 -9
- package/dist/index.d.ts +237 -9
- package/dist/index.js +444 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +429 -46
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2,6 +2,12 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
6
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
7
|
+
}) : x)(function(x) {
|
|
8
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
9
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
10
|
+
});
|
|
5
11
|
var __esm = (fn, res) => function __init() {
|
|
6
12
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
13
|
};
|
|
@@ -20,18 +26,33 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
20
26
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
27
|
|
|
22
28
|
// src/transport.ts
|
|
23
|
-
|
|
29
|
+
function safeJsonStringify(value) {
|
|
30
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
31
|
+
return JSON.stringify(value, (_key, val) => {
|
|
32
|
+
if (typeof val === "object" && val !== null) {
|
|
33
|
+
if (seen.has(val)) {
|
|
34
|
+
return "[Circular]";
|
|
35
|
+
}
|
|
36
|
+
seen.add(val);
|
|
37
|
+
}
|
|
38
|
+
return val;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
var DEFAULT_ENDPOINT, DEFAULT_TIMEOUT_MS, HttpTransport, NoopTransport, ConsoleTransport, BatchTransport;
|
|
24
42
|
var init_transport = __esm({
|
|
25
43
|
"src/transport.ts"() {
|
|
26
44
|
DEFAULT_ENDPOINT = "https://api.bugwatch.dev";
|
|
45
|
+
DEFAULT_TIMEOUT_MS = 1e4;
|
|
27
46
|
HttpTransport = class {
|
|
28
47
|
endpoint;
|
|
29
48
|
apiKey;
|
|
30
49
|
debug;
|
|
50
|
+
timeoutMs;
|
|
31
51
|
constructor(options) {
|
|
32
52
|
this.endpoint = options.endpoint || DEFAULT_ENDPOINT;
|
|
33
53
|
this.apiKey = options.apiKey;
|
|
34
54
|
this.debug = options.debug || false;
|
|
55
|
+
this.timeoutMs = DEFAULT_TIMEOUT_MS;
|
|
35
56
|
}
|
|
36
57
|
async send(event) {
|
|
37
58
|
const url = `${this.endpoint}/api/v1/events`;
|
|
@@ -39,35 +60,45 @@ var init_transport = __esm({
|
|
|
39
60
|
console.log("[Bugwatch] Sending event:", event.event_id);
|
|
40
61
|
}
|
|
41
62
|
try {
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const retryAfter = response.headers.get("Retry-After");
|
|
63
|
+
const controller = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
64
|
+
const timeoutId = controller ? setTimeout(() => controller.abort(), this.timeoutMs) : null;
|
|
65
|
+
try {
|
|
66
|
+
const response = await this.fetch(url, {
|
|
67
|
+
method: "POST",
|
|
68
|
+
headers: {
|
|
69
|
+
"Content-Type": "application/json",
|
|
70
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
71
|
+
"X-Bugwatch-SDK": event.sdk?.name || "bugwatch-core",
|
|
72
|
+
"X-Bugwatch-SDK-Version": event.sdk?.version || "0.1.0"
|
|
73
|
+
},
|
|
74
|
+
body: safeJsonStringify(event),
|
|
75
|
+
...controller && { signal: controller.signal }
|
|
76
|
+
});
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
const errorText = await response.text();
|
|
59
79
|
if (this.debug) {
|
|
60
|
-
console.
|
|
80
|
+
console.error("[Bugwatch] Failed to send event:", response.status, errorText);
|
|
81
|
+
}
|
|
82
|
+
if (response.status === 429) {
|
|
83
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
84
|
+
if (this.debug) {
|
|
85
|
+
console.warn(`[Bugwatch] Rate limited. Retry after ${retryAfter}s`);
|
|
86
|
+
}
|
|
61
87
|
}
|
|
88
|
+
throw new Error(`Failed to send event: ${response.status}`);
|
|
89
|
+
}
|
|
90
|
+
if (this.debug) {
|
|
91
|
+
console.log("[Bugwatch] Event sent successfully:", event.event_id);
|
|
92
|
+
}
|
|
93
|
+
} finally {
|
|
94
|
+
if (timeoutId !== null) {
|
|
95
|
+
clearTimeout(timeoutId);
|
|
62
96
|
}
|
|
63
|
-
throw new Error(`Failed to send event: ${response.status}`);
|
|
64
|
-
}
|
|
65
|
-
if (this.debug) {
|
|
66
|
-
console.log("[Bugwatch] Event sent successfully:", event.event_id);
|
|
67
97
|
}
|
|
68
98
|
} catch (error) {
|
|
69
99
|
if (this.debug) {
|
|
70
|
-
|
|
100
|
+
const message = error instanceof Error && error.name === "AbortError" ? `[Bugwatch] Request timed out after ${this.timeoutMs}ms` : "[Bugwatch] Transport error:";
|
|
101
|
+
console.error(message, error);
|
|
71
102
|
}
|
|
72
103
|
}
|
|
73
104
|
}
|
|
@@ -87,7 +118,7 @@ var init_transport = __esm({
|
|
|
87
118
|
};
|
|
88
119
|
ConsoleTransport = class {
|
|
89
120
|
async send(event) {
|
|
90
|
-
console.log("[Bugwatch Event]",
|
|
121
|
+
console.log("[Bugwatch Event]", safeJsonStringify(event));
|
|
91
122
|
}
|
|
92
123
|
};
|
|
93
124
|
BatchTransport = class {
|
|
@@ -113,7 +144,10 @@ var init_transport = __esm({
|
|
|
113
144
|
return;
|
|
114
145
|
}
|
|
115
146
|
const events = this.queue.splice(0, this.maxBatchSize);
|
|
116
|
-
await Promise.
|
|
147
|
+
const results = await Promise.allSettled(events.map((event) => this.transport.send(event)));
|
|
148
|
+
for (const result of results) {
|
|
149
|
+
if (result.status === "rejected") ;
|
|
150
|
+
}
|
|
117
151
|
}
|
|
118
152
|
startTimer() {
|
|
119
153
|
if (typeof setInterval !== "undefined") {
|
|
@@ -132,6 +166,13 @@ var init_transport = __esm({
|
|
|
132
166
|
this.timer = null;
|
|
133
167
|
}
|
|
134
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Close the transport, flushing any remaining events and stopping the timer.
|
|
171
|
+
*/
|
|
172
|
+
async close() {
|
|
173
|
+
await this.flush();
|
|
174
|
+
this.destroy();
|
|
175
|
+
}
|
|
135
176
|
};
|
|
136
177
|
}
|
|
137
178
|
});
|
|
@@ -280,6 +321,126 @@ var init_fingerprint = __esm({
|
|
|
280
321
|
}
|
|
281
322
|
});
|
|
282
323
|
|
|
324
|
+
// src/context.ts
|
|
325
|
+
var context_exports = {};
|
|
326
|
+
__export(context_exports, {
|
|
327
|
+
addRequestBreadcrumb: () => addRequestBreadcrumb,
|
|
328
|
+
createScopedContext: () => createScopedContext,
|
|
329
|
+
getMergedContext: () => getMergedContext,
|
|
330
|
+
getRequestContext: () => getRequestContext,
|
|
331
|
+
hasRequestContext: () => hasRequestContext,
|
|
332
|
+
runWithContext: () => runWithContext,
|
|
333
|
+
runWithContextAsync: () => runWithContextAsync,
|
|
334
|
+
setRequestExtra: () => setRequestExtra,
|
|
335
|
+
setRequestTag: () => setRequestTag,
|
|
336
|
+
setRequestUser: () => setRequestUser
|
|
337
|
+
});
|
|
338
|
+
function createScopedContext() {
|
|
339
|
+
return {
|
|
340
|
+
user: null,
|
|
341
|
+
tags: {},
|
|
342
|
+
extra: {},
|
|
343
|
+
breadcrumbs: []
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
function isNodeEnvironment() {
|
|
347
|
+
return typeof process !== "undefined" && process.versions?.node !== void 0 && typeof __require !== "undefined";
|
|
348
|
+
}
|
|
349
|
+
function getAsyncLocalStorage() {
|
|
350
|
+
if (asyncLocalStorage) {
|
|
351
|
+
return asyncLocalStorage;
|
|
352
|
+
}
|
|
353
|
+
if (!isNodeEnvironment()) {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
try {
|
|
357
|
+
const asyncHooks = __require("async_hooks");
|
|
358
|
+
asyncLocalStorage = new asyncHooks.AsyncLocalStorage();
|
|
359
|
+
return asyncLocalStorage;
|
|
360
|
+
} catch {
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
function runWithContext(context, fn) {
|
|
365
|
+
const storage = getAsyncLocalStorage();
|
|
366
|
+
if (storage) {
|
|
367
|
+
return storage.run(context, fn);
|
|
368
|
+
}
|
|
369
|
+
return fn();
|
|
370
|
+
}
|
|
371
|
+
async function runWithContextAsync(context, fn) {
|
|
372
|
+
const storage = getAsyncLocalStorage();
|
|
373
|
+
if (storage) {
|
|
374
|
+
return storage.run(context, fn);
|
|
375
|
+
}
|
|
376
|
+
return fn();
|
|
377
|
+
}
|
|
378
|
+
function getRequestContext() {
|
|
379
|
+
const storage = getAsyncLocalStorage();
|
|
380
|
+
return storage?.getStore();
|
|
381
|
+
}
|
|
382
|
+
function hasRequestContext() {
|
|
383
|
+
return getRequestContext() !== void 0;
|
|
384
|
+
}
|
|
385
|
+
function setRequestUser(user) {
|
|
386
|
+
const ctx = getRequestContext();
|
|
387
|
+
if (ctx) {
|
|
388
|
+
ctx.user = user;
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
function setRequestTag(key, value) {
|
|
394
|
+
const ctx = getRequestContext();
|
|
395
|
+
if (ctx) {
|
|
396
|
+
ctx.tags[key] = value;
|
|
397
|
+
return true;
|
|
398
|
+
}
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
function setRequestExtra(key, value) {
|
|
402
|
+
const ctx = getRequestContext();
|
|
403
|
+
if (ctx) {
|
|
404
|
+
ctx.extra[key] = value;
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
function addRequestBreadcrumb(breadcrumb, maxBreadcrumbs = 100) {
|
|
410
|
+
const ctx = getRequestContext();
|
|
411
|
+
if (ctx) {
|
|
412
|
+
ctx.breadcrumbs.push(breadcrumb);
|
|
413
|
+
if (ctx.breadcrumbs.length > maxBreadcrumbs) {
|
|
414
|
+
ctx.breadcrumbs = ctx.breadcrumbs.slice(-maxBreadcrumbs);
|
|
415
|
+
}
|
|
416
|
+
return true;
|
|
417
|
+
}
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
function getMergedContext(globalUser, globalTags, globalExtra, globalBreadcrumbs) {
|
|
421
|
+
const reqCtx = getRequestContext();
|
|
422
|
+
if (!reqCtx) {
|
|
423
|
+
return {
|
|
424
|
+
user: globalUser,
|
|
425
|
+
tags: globalTags,
|
|
426
|
+
extra: globalExtra,
|
|
427
|
+
breadcrumbs: globalBreadcrumbs
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
return {
|
|
431
|
+
user: reqCtx.user || globalUser,
|
|
432
|
+
tags: { ...globalTags, ...reqCtx.tags },
|
|
433
|
+
extra: { ...globalExtra, ...reqCtx.extra },
|
|
434
|
+
breadcrumbs: [...globalBreadcrumbs, ...reqCtx.breadcrumbs]
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
var asyncLocalStorage;
|
|
438
|
+
var init_context = __esm({
|
|
439
|
+
"src/context.ts"() {
|
|
440
|
+
asyncLocalStorage = null;
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
|
|
283
444
|
// src/client.ts
|
|
284
445
|
var client_exports = {};
|
|
285
446
|
__export(client_exports, {
|
|
@@ -290,12 +451,52 @@ function generateEventId() {
|
|
|
290
451
|
const random = Math.random().toString(36).substring(2, 10);
|
|
291
452
|
return `${timestamp}${random}`;
|
|
292
453
|
}
|
|
293
|
-
var SDK_NAME, SDK_VERSION, DEFAULT_OPTIONS, Bugwatch;
|
|
454
|
+
var RingBuffer, SDK_NAME, SDK_VERSION, DEFAULT_OPTIONS, Bugwatch;
|
|
294
455
|
var init_client = __esm({
|
|
295
456
|
"src/client.ts"() {
|
|
296
457
|
init_transport();
|
|
297
458
|
init_stacktrace();
|
|
298
459
|
init_fingerprint();
|
|
460
|
+
init_context();
|
|
461
|
+
RingBuffer = class {
|
|
462
|
+
constructor(maxSize) {
|
|
463
|
+
this.maxSize = maxSize;
|
|
464
|
+
this.buffer = new Array(maxSize);
|
|
465
|
+
}
|
|
466
|
+
buffer;
|
|
467
|
+
head = 0;
|
|
468
|
+
count = 0;
|
|
469
|
+
push(item) {
|
|
470
|
+
this.buffer[this.head] = item;
|
|
471
|
+
this.head = (this.head + 1) % this.maxSize;
|
|
472
|
+
if (this.count < this.maxSize) {
|
|
473
|
+
this.count++;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
toArray() {
|
|
477
|
+
if (this.count === 0) {
|
|
478
|
+
return [];
|
|
479
|
+
}
|
|
480
|
+
const result = [];
|
|
481
|
+
const start = this.count < this.maxSize ? 0 : this.head;
|
|
482
|
+
for (let i = 0; i < this.count; i++) {
|
|
483
|
+
const index = (start + i) % this.maxSize;
|
|
484
|
+
const item = this.buffer[index];
|
|
485
|
+
if (item !== void 0) {
|
|
486
|
+
result.push(item);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
return result;
|
|
490
|
+
}
|
|
491
|
+
clear() {
|
|
492
|
+
this.buffer = new Array(this.maxSize);
|
|
493
|
+
this.head = 0;
|
|
494
|
+
this.count = 0;
|
|
495
|
+
}
|
|
496
|
+
get length() {
|
|
497
|
+
return this.count;
|
|
498
|
+
}
|
|
499
|
+
};
|
|
299
500
|
SDK_NAME = "@bugwatch/core";
|
|
300
501
|
SDK_VERSION = "0.1.0";
|
|
301
502
|
DEFAULT_OPTIONS = {
|
|
@@ -308,7 +509,7 @@ var init_client = __esm({
|
|
|
308
509
|
Bugwatch = class {
|
|
309
510
|
options;
|
|
310
511
|
transport;
|
|
311
|
-
breadcrumbs
|
|
512
|
+
breadcrumbs;
|
|
312
513
|
tags = {};
|
|
313
514
|
extra = {};
|
|
314
515
|
user = null;
|
|
@@ -317,6 +518,7 @@ var init_client = __esm({
|
|
|
317
518
|
constructor(options) {
|
|
318
519
|
this.options = { ...DEFAULT_OPTIONS, ...options };
|
|
319
520
|
this.transport = this.createTransport();
|
|
521
|
+
this.breadcrumbs = new RingBuffer(this.options.maxBreadcrumbs || 100);
|
|
320
522
|
if (options.tags) {
|
|
321
523
|
this.tags = { ...options.tags };
|
|
322
524
|
}
|
|
@@ -362,7 +564,17 @@ var init_client = __esm({
|
|
|
362
564
|
return "";
|
|
363
565
|
}
|
|
364
566
|
const event = this.createEventFromError(error, context);
|
|
365
|
-
|
|
567
|
+
let processedEvent = event;
|
|
568
|
+
if (this.options.beforeSend) {
|
|
569
|
+
try {
|
|
570
|
+
processedEvent = this.options.beforeSend(event);
|
|
571
|
+
} catch (err) {
|
|
572
|
+
if (this.options.debug) {
|
|
573
|
+
console.error("[Bugwatch] beforeSend threw an error:", err);
|
|
574
|
+
}
|
|
575
|
+
processedEvent = event;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
366
578
|
if (!processedEvent) {
|
|
367
579
|
if (this.options.debug) {
|
|
368
580
|
console.log("[Bugwatch] Event dropped by beforeSend");
|
|
@@ -384,7 +596,17 @@ var init_client = __esm({
|
|
|
384
596
|
message,
|
|
385
597
|
level
|
|
386
598
|
});
|
|
387
|
-
|
|
599
|
+
let processedEvent = event;
|
|
600
|
+
if (this.options.beforeSend) {
|
|
601
|
+
try {
|
|
602
|
+
processedEvent = this.options.beforeSend(event);
|
|
603
|
+
} catch (err) {
|
|
604
|
+
if (this.options.debug) {
|
|
605
|
+
console.error("[Bugwatch] beforeSend threw an error:", err);
|
|
606
|
+
}
|
|
607
|
+
processedEvent = event;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
388
610
|
if (!processedEvent) {
|
|
389
611
|
return "";
|
|
390
612
|
}
|
|
@@ -401,10 +623,6 @@ var init_client = __esm({
|
|
|
401
623
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
402
624
|
};
|
|
403
625
|
this.breadcrumbs.push(crumb);
|
|
404
|
-
const max = this.options.maxBreadcrumbs || 100;
|
|
405
|
-
if (this.breadcrumbs.length > max) {
|
|
406
|
-
this.breadcrumbs = this.breadcrumbs.slice(-max);
|
|
407
|
-
}
|
|
408
626
|
}
|
|
409
627
|
/**
|
|
410
628
|
* Set user context
|
|
@@ -428,7 +646,7 @@ var init_client = __esm({
|
|
|
428
646
|
* Clear breadcrumbs
|
|
429
647
|
*/
|
|
430
648
|
clearBreadcrumbs() {
|
|
431
|
-
this.breadcrumbs
|
|
649
|
+
this.breadcrumbs.clear();
|
|
432
650
|
}
|
|
433
651
|
/**
|
|
434
652
|
* Create an event from an Error object
|
|
@@ -452,6 +670,12 @@ var init_client = __esm({
|
|
|
452
670
|
* Create a base event
|
|
453
671
|
*/
|
|
454
672
|
createEvent(partial) {
|
|
673
|
+
const mergedContext = getMergedContext(
|
|
674
|
+
this.user,
|
|
675
|
+
this.tags,
|
|
676
|
+
this.extra,
|
|
677
|
+
this.breadcrumbs.toArray()
|
|
678
|
+
);
|
|
455
679
|
const event = {
|
|
456
680
|
event_id: generateEventId(),
|
|
457
681
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -460,17 +684,17 @@ var init_client = __esm({
|
|
|
460
684
|
message: partial.message || "",
|
|
461
685
|
environment: this.options.environment,
|
|
462
686
|
release: this.options.release,
|
|
463
|
-
tags: { ...
|
|
464
|
-
extra: { ...
|
|
465
|
-
breadcrumbs:
|
|
687
|
+
tags: { ...mergedContext.tags, ...partial.tags },
|
|
688
|
+
extra: { ...mergedContext.extra, ...partial.extra },
|
|
689
|
+
breadcrumbs: mergedContext.breadcrumbs,
|
|
466
690
|
sdk: {
|
|
467
691
|
name: SDK_NAME,
|
|
468
692
|
version: SDK_VERSION
|
|
469
693
|
},
|
|
470
694
|
...partial
|
|
471
695
|
};
|
|
472
|
-
if (
|
|
473
|
-
event.user = { ...
|
|
696
|
+
if (mergedContext.user || partial.user) {
|
|
697
|
+
event.user = { ...mergedContext.user, ...partial.user };
|
|
474
698
|
}
|
|
475
699
|
if (event.exception) {
|
|
476
700
|
const fingerprint = fingerprintFromException(event.exception);
|
|
@@ -514,6 +738,95 @@ var init_client = __esm({
|
|
|
514
738
|
}
|
|
515
739
|
return "javascript";
|
|
516
740
|
}
|
|
741
|
+
/**
|
|
742
|
+
* Flush any pending events.
|
|
743
|
+
* Call this before process exit to ensure no events are lost.
|
|
744
|
+
*/
|
|
745
|
+
async flush() {
|
|
746
|
+
if (this.transport.flush) {
|
|
747
|
+
await this.transport.flush();
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Close the client and release any resources.
|
|
752
|
+
* This flushes any pending events and closes the transport.
|
|
753
|
+
* After calling this method, the client should not be used again.
|
|
754
|
+
*/
|
|
755
|
+
async close() {
|
|
756
|
+
if (this.transport.close) {
|
|
757
|
+
await this.transport.close();
|
|
758
|
+
} else {
|
|
759
|
+
await this.flush();
|
|
760
|
+
}
|
|
761
|
+
this.initialized = false;
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
|
|
767
|
+
// src/env.ts
|
|
768
|
+
var env_exports = {};
|
|
769
|
+
__export(env_exports, {
|
|
770
|
+
ENV_VARS: () => ENV_VARS,
|
|
771
|
+
getEnvConfig: () => getEnvConfig,
|
|
772
|
+
hasApiKey: () => hasApiKey,
|
|
773
|
+
validateApiKey: () => validateApiKey
|
|
774
|
+
});
|
|
775
|
+
function getEnvVar(name) {
|
|
776
|
+
if (typeof process !== "undefined" && process.env) {
|
|
777
|
+
return process.env[name];
|
|
778
|
+
}
|
|
779
|
+
return void 0;
|
|
780
|
+
}
|
|
781
|
+
function getEnvConfig() {
|
|
782
|
+
const config = {};
|
|
783
|
+
const apiKey = getEnvVar(ENV_VARS.API_KEY);
|
|
784
|
+
if (apiKey) {
|
|
785
|
+
config.apiKey = apiKey;
|
|
786
|
+
}
|
|
787
|
+
const environment = getEnvVar(ENV_VARS.ENVIRONMENT);
|
|
788
|
+
if (environment) {
|
|
789
|
+
config.environment = environment;
|
|
790
|
+
}
|
|
791
|
+
const release = getEnvVar(ENV_VARS.RELEASE);
|
|
792
|
+
if (release) {
|
|
793
|
+
config.release = release;
|
|
794
|
+
}
|
|
795
|
+
const debug = getEnvVar(ENV_VARS.DEBUG);
|
|
796
|
+
if (debug === "true") {
|
|
797
|
+
config.debug = true;
|
|
798
|
+
}
|
|
799
|
+
const endpoint = getEnvVar(ENV_VARS.ENDPOINT);
|
|
800
|
+
if (endpoint) {
|
|
801
|
+
config.endpoint = endpoint;
|
|
802
|
+
}
|
|
803
|
+
return config;
|
|
804
|
+
}
|
|
805
|
+
function validateApiKey(key) {
|
|
806
|
+
if (!key) {
|
|
807
|
+
throw new Error(
|
|
808
|
+
"Bugwatch: API key required. Set BUGWATCH_API_KEY environment variable or pass { apiKey: '...' }"
|
|
809
|
+
);
|
|
810
|
+
}
|
|
811
|
+
if (!key.startsWith("bw_")) {
|
|
812
|
+
const preview = key.length > 10 ? `${key.slice(0, 6)}...` : "[hidden]";
|
|
813
|
+
console.warn(
|
|
814
|
+
`Bugwatch: API key should start with 'bw_'. Got '${preview}'`
|
|
815
|
+
);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
function hasApiKey(explicitKey) {
|
|
819
|
+
return Boolean(explicitKey || getEnvVar(ENV_VARS.API_KEY));
|
|
820
|
+
}
|
|
821
|
+
var ENV_VARS;
|
|
822
|
+
var init_env = __esm({
|
|
823
|
+
"src/env.ts"() {
|
|
824
|
+
ENV_VARS = {
|
|
825
|
+
API_KEY: "BUGWATCH_API_KEY",
|
|
826
|
+
ENVIRONMENT: "BUGWATCH_ENVIRONMENT",
|
|
827
|
+
RELEASE: "BUGWATCH_RELEASE",
|
|
828
|
+
DEBUG: "BUGWATCH_DEBUG",
|
|
829
|
+
ENDPOINT: "BUGWATCH_ENDPOINT"
|
|
517
830
|
};
|
|
518
831
|
}
|
|
519
832
|
});
|
|
@@ -523,26 +836,57 @@ init_client();
|
|
|
523
836
|
init_transport();
|
|
524
837
|
init_stacktrace();
|
|
525
838
|
init_fingerprint();
|
|
839
|
+
init_env();
|
|
840
|
+
init_context();
|
|
526
841
|
var globalClient = null;
|
|
842
|
+
var lazyInitWarned = false;
|
|
527
843
|
function init(options) {
|
|
528
844
|
const { Bugwatch: Bugwatch2 } = (init_client(), __toCommonJS(client_exports));
|
|
529
|
-
const
|
|
845
|
+
const { getEnvConfig: getEnvConfig2, validateApiKey: validateApiKey2 } = (init_env(), __toCommonJS(env_exports));
|
|
846
|
+
const envConfig = getEnvConfig2();
|
|
847
|
+
const mergedOptions = { ...envConfig, ...options };
|
|
848
|
+
validateApiKey2(mergedOptions.apiKey);
|
|
849
|
+
const client = new Bugwatch2(mergedOptions);
|
|
530
850
|
globalClient = client;
|
|
851
|
+
lazyInitWarned = false;
|
|
531
852
|
return client;
|
|
532
853
|
}
|
|
533
854
|
function getClient() {
|
|
534
855
|
return globalClient;
|
|
535
856
|
}
|
|
857
|
+
function tryLazyInit() {
|
|
858
|
+
if (globalClient) return true;
|
|
859
|
+
const { getEnvConfig: getEnvConfig2, hasApiKey: hasApiKey2 } = (init_env(), __toCommonJS(env_exports));
|
|
860
|
+
if (!hasApiKey2()) {
|
|
861
|
+
return false;
|
|
862
|
+
}
|
|
863
|
+
try {
|
|
864
|
+
const { Bugwatch: Bugwatch2 } = (init_client(), __toCommonJS(client_exports));
|
|
865
|
+
const envConfig = getEnvConfig2();
|
|
866
|
+
if (!envConfig.apiKey) {
|
|
867
|
+
return false;
|
|
868
|
+
}
|
|
869
|
+
const client = new Bugwatch2(envConfig);
|
|
870
|
+
globalClient = client;
|
|
871
|
+
if (envConfig.debug && !lazyInitWarned) {
|
|
872
|
+
console.warn("[Bugwatch] Auto-initialized from BUGWATCH_API_KEY environment variable");
|
|
873
|
+
lazyInitWarned = true;
|
|
874
|
+
}
|
|
875
|
+
return true;
|
|
876
|
+
} catch {
|
|
877
|
+
return false;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
536
880
|
function captureException(error, context) {
|
|
537
|
-
if (!globalClient) {
|
|
538
|
-
console.warn("[Bugwatch] SDK not initialized. Call init() first.");
|
|
881
|
+
if (!globalClient && !tryLazyInit()) {
|
|
882
|
+
console.warn("[Bugwatch] SDK not initialized. Call init() first or set BUGWATCH_API_KEY environment variable.");
|
|
539
883
|
return "";
|
|
540
884
|
}
|
|
541
885
|
return globalClient.captureException(error, context);
|
|
542
886
|
}
|
|
543
887
|
function captureMessage(message, level) {
|
|
544
|
-
if (!globalClient) {
|
|
545
|
-
console.warn("[Bugwatch] SDK not initialized. Call init() first.");
|
|
888
|
+
if (!globalClient && !tryLazyInit()) {
|
|
889
|
+
console.warn("[Bugwatch] SDK not initialized. Call init() first or set BUGWATCH_API_KEY environment variable.");
|
|
546
890
|
return "";
|
|
547
891
|
}
|
|
548
892
|
return globalClient.captureMessage(message, level);
|
|
@@ -551,27 +895,66 @@ function addBreadcrumb(breadcrumb) {
|
|
|
551
895
|
if (!globalClient) {
|
|
552
896
|
return;
|
|
553
897
|
}
|
|
898
|
+
const { addRequestBreadcrumb: addRequestBreadcrumb2 } = (init_context(), __toCommonJS(context_exports));
|
|
899
|
+
const crumb = {
|
|
900
|
+
...breadcrumb,
|
|
901
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
902
|
+
};
|
|
903
|
+
if (addRequestBreadcrumb2(crumb, globalClient.getOptions().maxBreadcrumbs || 100)) {
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
554
906
|
globalClient.addBreadcrumb(breadcrumb);
|
|
555
907
|
}
|
|
556
908
|
function setUser(user) {
|
|
557
909
|
if (!globalClient) {
|
|
558
910
|
return;
|
|
559
911
|
}
|
|
912
|
+
const { setRequestUser: setRequestUser2 } = (init_context(), __toCommonJS(context_exports));
|
|
913
|
+
if (setRequestUser2(user)) {
|
|
914
|
+
return;
|
|
915
|
+
}
|
|
560
916
|
globalClient.setUser(user);
|
|
561
917
|
}
|
|
562
918
|
function setTag(key, value) {
|
|
563
919
|
if (!globalClient) {
|
|
564
920
|
return;
|
|
565
921
|
}
|
|
922
|
+
const { setRequestTag: setRequestTag2 } = (init_context(), __toCommonJS(context_exports));
|
|
923
|
+
if (setRequestTag2(key, value)) {
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
566
926
|
globalClient.setTag(key, value);
|
|
567
927
|
}
|
|
568
928
|
function setExtra(key, value) {
|
|
569
929
|
if (!globalClient) {
|
|
570
930
|
return;
|
|
571
931
|
}
|
|
932
|
+
const { setRequestExtra: setRequestExtra2 } = (init_context(), __toCommonJS(context_exports));
|
|
933
|
+
if (setRequestExtra2(key, value)) {
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
572
936
|
globalClient.setExtra(key, value);
|
|
573
937
|
}
|
|
938
|
+
async function flush() {
|
|
939
|
+
if (!globalClient) {
|
|
940
|
+
console.warn("[Bugwatch] SDK not initialized. Call init() first.");
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
await globalClient.flush();
|
|
944
|
+
}
|
|
945
|
+
async function close() {
|
|
946
|
+
if (!globalClient) {
|
|
947
|
+
console.warn("[Bugwatch] SDK not initialized. Call init() first.");
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
await globalClient.close();
|
|
951
|
+
globalClient = null;
|
|
952
|
+
}
|
|
953
|
+
function reset() {
|
|
954
|
+
globalClient = null;
|
|
955
|
+
lazyInitWarned = false;
|
|
956
|
+
}
|
|
574
957
|
|
|
575
|
-
export { BatchTransport, Bugwatch, ConsoleTransport, HttpTransport, NoopTransport, addBreadcrumb, captureException, captureMessage, extractErrorInfo, fingerprintFromException, generateFingerprint, getClient, init, parseStackTrace, setExtra, setTag, setUser };
|
|
958
|
+
export { BatchTransport, Bugwatch, ConsoleTransport, ENV_VARS, HttpTransport, NoopTransport, addBreadcrumb, addRequestBreadcrumb, captureException, captureMessage, close, createScopedContext, extractErrorInfo, fingerprintFromException, flush, generateFingerprint, getClient, getEnvConfig, getMergedContext, getRequestContext, hasApiKey, hasRequestContext, init, parseStackTrace, reset, runWithContext, runWithContextAsync, setExtra, setRequestExtra, setRequestTag, setRequestUser, setTag, setUser, validateApiKey };
|
|
576
959
|
//# sourceMappingURL=index.mjs.map
|
|
577
960
|
//# sourceMappingURL=index.mjs.map
|