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