brakit 0.10.0 → 0.10.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/api.d.ts +6 -5
- package/dist/api.js +23 -15
- package/dist/bin/brakit.js +120 -25
- package/dist/dashboard-client.global.js +470 -424
- package/dist/dashboard.html +558 -472
- package/dist/mcp/server.js +98 -22
- package/dist/runtime/index.js +361 -269
- package/package.json +1 -1
package/dist/runtime/index.js
CHANGED
|
@@ -105,11 +105,14 @@ var init_config = __esm({
|
|
|
105
105
|
"nuxt",
|
|
106
106
|
"vite",
|
|
107
107
|
"astro",
|
|
108
|
+
"@nestjs/core",
|
|
109
|
+
"@adonisjs/core",
|
|
110
|
+
"sails",
|
|
108
111
|
"express",
|
|
109
112
|
"fastify",
|
|
110
113
|
"hono",
|
|
111
114
|
"koa",
|
|
112
|
-
"
|
|
115
|
+
"@hapi/hapi",
|
|
113
116
|
"prisma",
|
|
114
117
|
"drizzle-orm",
|
|
115
118
|
"typeorm",
|
|
@@ -145,14 +148,10 @@ var init_labels = __esm({
|
|
|
145
148
|
VALID_TABS_TUPLE = [
|
|
146
149
|
"overview",
|
|
147
150
|
"actions",
|
|
148
|
-
"
|
|
149
|
-
"fetches",
|
|
150
|
-
"queries",
|
|
151
|
-
"errors",
|
|
152
|
-
"logs",
|
|
151
|
+
"insights",
|
|
153
152
|
"performance",
|
|
154
|
-
"
|
|
155
|
-
"
|
|
153
|
+
"graph",
|
|
154
|
+
"explorer"
|
|
156
155
|
];
|
|
157
156
|
VALID_TABS = new Set(VALID_TABS_TUPLE);
|
|
158
157
|
BRAKIT_REQUEST_ID_HEADER = "x-brakit-request-id";
|
|
@@ -339,6 +338,214 @@ var init_fetch = __esm({
|
|
|
339
338
|
}
|
|
340
339
|
});
|
|
341
340
|
|
|
341
|
+
// src/utils/log.ts
|
|
342
|
+
function brakitWarn(message) {
|
|
343
|
+
process.stderr.write(`${PREFIX} ${message}
|
|
344
|
+
`);
|
|
345
|
+
}
|
|
346
|
+
function brakitDebug(message) {
|
|
347
|
+
if (process.env.DEBUG_BRAKIT) {
|
|
348
|
+
process.stderr.write(`${PREFIX}:debug ${message}
|
|
349
|
+
`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
var PREFIX;
|
|
353
|
+
var init_log = __esm({
|
|
354
|
+
"src/utils/log.ts"() {
|
|
355
|
+
"use strict";
|
|
356
|
+
PREFIX = "[brakit]";
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// src/utils/type-guards.ts
|
|
361
|
+
function isString(val) {
|
|
362
|
+
return typeof val === "string";
|
|
363
|
+
}
|
|
364
|
+
function isNumber(val) {
|
|
365
|
+
return typeof val === "number" && !isNaN(val);
|
|
366
|
+
}
|
|
367
|
+
function isBoolean(val) {
|
|
368
|
+
return typeof val === "boolean";
|
|
369
|
+
}
|
|
370
|
+
function isThenable(value) {
|
|
371
|
+
return value != null && typeof value.then === "function";
|
|
372
|
+
}
|
|
373
|
+
function getErrorMessage(err) {
|
|
374
|
+
if (err instanceof Error) return err.message;
|
|
375
|
+
if (typeof err === "string") return err;
|
|
376
|
+
return String(err);
|
|
377
|
+
}
|
|
378
|
+
function isValidIssueState(val) {
|
|
379
|
+
return typeof val === "string" && VALID_ISSUE_STATES.has(val);
|
|
380
|
+
}
|
|
381
|
+
function isValidIssueCategory(val) {
|
|
382
|
+
return typeof val === "string" && VALID_ISSUE_CATEGORIES.has(val);
|
|
383
|
+
}
|
|
384
|
+
function isValidAiFixStatus(val) {
|
|
385
|
+
return typeof val === "string" && VALID_AI_FIX_STATUSES.has(val);
|
|
386
|
+
}
|
|
387
|
+
function validateIssuesData(parsed) {
|
|
388
|
+
if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
389
|
+
const obj = parsed;
|
|
390
|
+
if (obj.version === ISSUES_DATA_VERSION && Array.isArray(obj.issues)) {
|
|
391
|
+
return parsed;
|
|
392
|
+
}
|
|
393
|
+
return null;
|
|
394
|
+
}
|
|
395
|
+
function validateMetricsData(parsed) {
|
|
396
|
+
if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
397
|
+
const obj = parsed;
|
|
398
|
+
if (obj.version === 1 && Array.isArray(obj.endpoints)) {
|
|
399
|
+
return parsed;
|
|
400
|
+
}
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
var init_type_guards = __esm({
|
|
404
|
+
"src/utils/type-guards.ts"() {
|
|
405
|
+
"use strict";
|
|
406
|
+
init_config();
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
// src/runtime/capture.ts
|
|
411
|
+
import { gunzip, brotliDecompress, inflate } from "zlib";
|
|
412
|
+
function outgoingToIncoming(headers2) {
|
|
413
|
+
const result = {};
|
|
414
|
+
for (const [key, value] of Object.entries(headers2)) {
|
|
415
|
+
if (value === void 0) continue;
|
|
416
|
+
if (Array.isArray(value)) {
|
|
417
|
+
result[key] = value.map(String);
|
|
418
|
+
} else {
|
|
419
|
+
result[key] = String(value);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return result;
|
|
423
|
+
}
|
|
424
|
+
function getDecompressor(encoding) {
|
|
425
|
+
if (encoding === CONTENT_ENCODING_GZIP) return gunzip;
|
|
426
|
+
if (encoding === CONTENT_ENCODING_BR) return brotliDecompress;
|
|
427
|
+
if (encoding === CONTENT_ENCODING_DEFLATE) return inflate;
|
|
428
|
+
return null;
|
|
429
|
+
}
|
|
430
|
+
function decompressAsync(body, encoding) {
|
|
431
|
+
const decompressor = getDecompressor(encoding);
|
|
432
|
+
if (!decompressor) return Promise.resolve(body);
|
|
433
|
+
return new Promise((resolve6) => {
|
|
434
|
+
decompressor(body, (err, result) => {
|
|
435
|
+
resolve6(err ? body : result);
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
function toBuffer(chunk) {
|
|
440
|
+
if (Buffer.isBuffer(chunk)) return chunk;
|
|
441
|
+
if (chunk instanceof Uint8Array) return Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
442
|
+
if (typeof chunk === "string") return Buffer.from(chunk);
|
|
443
|
+
return null;
|
|
444
|
+
}
|
|
445
|
+
function drainPendingCaptures() {
|
|
446
|
+
if (pendingCaptures === 0) return Promise.resolve();
|
|
447
|
+
return new Promise((resolve6) => {
|
|
448
|
+
drainResolvers.push(resolve6);
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
function onCaptureSettled() {
|
|
452
|
+
pendingCaptures--;
|
|
453
|
+
if (pendingCaptures === 0 && drainResolvers.length > 0) {
|
|
454
|
+
const resolvers = drainResolvers;
|
|
455
|
+
drainResolvers = [];
|
|
456
|
+
for (const resolve6 of resolvers) resolve6();
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
function captureInProcess(req, res, requestId, requestStore, isChild = false) {
|
|
460
|
+
const startTime = performance.now();
|
|
461
|
+
const method = req.method ?? "GET";
|
|
462
|
+
const resChunks = [];
|
|
463
|
+
let resSize = 0;
|
|
464
|
+
const originalWrite = res.write;
|
|
465
|
+
const originalEnd = res.end;
|
|
466
|
+
let truncated = false;
|
|
467
|
+
res.write = function(...args) {
|
|
468
|
+
try {
|
|
469
|
+
const chunk = args[0];
|
|
470
|
+
if (chunk != null && typeof chunk !== "function") {
|
|
471
|
+
if (resSize < DEFAULT_MAX_BODY_CAPTURE) {
|
|
472
|
+
const buf = toBuffer(chunk);
|
|
473
|
+
if (buf) {
|
|
474
|
+
resChunks.push(buf);
|
|
475
|
+
resSize += buf.length;
|
|
476
|
+
}
|
|
477
|
+
} else {
|
|
478
|
+
truncated = true;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
} catch (e) {
|
|
482
|
+
brakitDebug(`capture write: ${getErrorMessage(e)}`);
|
|
483
|
+
}
|
|
484
|
+
return originalWrite.apply(this, args);
|
|
485
|
+
};
|
|
486
|
+
res.end = function(...args) {
|
|
487
|
+
try {
|
|
488
|
+
const chunk = typeof args[0] !== "function" ? args[0] : void 0;
|
|
489
|
+
if (chunk != null && resSize < DEFAULT_MAX_BODY_CAPTURE) {
|
|
490
|
+
const buf = toBuffer(chunk);
|
|
491
|
+
if (buf) {
|
|
492
|
+
resChunks.push(buf);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
} catch (e) {
|
|
496
|
+
brakitDebug(`capture end: ${getErrorMessage(e)}`);
|
|
497
|
+
}
|
|
498
|
+
const result = originalEnd.apply(this, args);
|
|
499
|
+
const endTime = performance.now();
|
|
500
|
+
const encoding = String(res.getHeader("content-encoding") ?? "").toLowerCase();
|
|
501
|
+
const statusCode = res.statusCode;
|
|
502
|
+
const responseHeaders = outgoingToIncoming(res.getHeaders());
|
|
503
|
+
const responseContentType = String(res.getHeader("content-type") ?? "");
|
|
504
|
+
const capturedChunks = resChunks.slice();
|
|
505
|
+
if (!isChild) {
|
|
506
|
+
pendingCaptures++;
|
|
507
|
+
void (async () => {
|
|
508
|
+
try {
|
|
509
|
+
let body = capturedChunks.length > 0 ? Buffer.concat(capturedChunks) : null;
|
|
510
|
+
if (body && encoding && !truncated) {
|
|
511
|
+
body = await decompressAsync(body, encoding);
|
|
512
|
+
}
|
|
513
|
+
requestStore.capture({
|
|
514
|
+
requestId,
|
|
515
|
+
method,
|
|
516
|
+
url: req.url ?? "/",
|
|
517
|
+
requestHeaders: req.headers,
|
|
518
|
+
requestBody: null,
|
|
519
|
+
statusCode,
|
|
520
|
+
responseHeaders,
|
|
521
|
+
responseBody: body,
|
|
522
|
+
responseContentType,
|
|
523
|
+
startTime,
|
|
524
|
+
endTime,
|
|
525
|
+
config: { maxBodyCapture: DEFAULT_MAX_BODY_CAPTURE }
|
|
526
|
+
});
|
|
527
|
+
} catch (e) {
|
|
528
|
+
brakitDebug(`capture store: ${getErrorMessage(e)}`);
|
|
529
|
+
} finally {
|
|
530
|
+
onCaptureSettled();
|
|
531
|
+
}
|
|
532
|
+
})();
|
|
533
|
+
}
|
|
534
|
+
return result;
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
var pendingCaptures, drainResolvers;
|
|
538
|
+
var init_capture = __esm({
|
|
539
|
+
"src/runtime/capture.ts"() {
|
|
540
|
+
"use strict";
|
|
541
|
+
init_constants();
|
|
542
|
+
init_log();
|
|
543
|
+
init_type_guards();
|
|
544
|
+
pendingCaptures = 0;
|
|
545
|
+
drainResolvers = [];
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
|
|
342
549
|
// src/instrument/hooks/console.ts
|
|
343
550
|
import { format } from "util";
|
|
344
551
|
function setupConsoleHook(emit) {
|
|
@@ -539,75 +746,6 @@ var init_normalize = __esm({
|
|
|
539
746
|
}
|
|
540
747
|
});
|
|
541
748
|
|
|
542
|
-
// src/utils/type-guards.ts
|
|
543
|
-
function isString(val) {
|
|
544
|
-
return typeof val === "string";
|
|
545
|
-
}
|
|
546
|
-
function isNumber(val) {
|
|
547
|
-
return typeof val === "number" && !isNaN(val);
|
|
548
|
-
}
|
|
549
|
-
function isBoolean(val) {
|
|
550
|
-
return typeof val === "boolean";
|
|
551
|
-
}
|
|
552
|
-
function isThenable(value) {
|
|
553
|
-
return value != null && typeof value.then === "function";
|
|
554
|
-
}
|
|
555
|
-
function getErrorMessage(err) {
|
|
556
|
-
if (err instanceof Error) return err.message;
|
|
557
|
-
if (typeof err === "string") return err;
|
|
558
|
-
return String(err);
|
|
559
|
-
}
|
|
560
|
-
function isValidIssueState(val) {
|
|
561
|
-
return typeof val === "string" && VALID_ISSUE_STATES.has(val);
|
|
562
|
-
}
|
|
563
|
-
function isValidIssueCategory(val) {
|
|
564
|
-
return typeof val === "string" && VALID_ISSUE_CATEGORIES.has(val);
|
|
565
|
-
}
|
|
566
|
-
function isValidAiFixStatus(val) {
|
|
567
|
-
return typeof val === "string" && VALID_AI_FIX_STATUSES.has(val);
|
|
568
|
-
}
|
|
569
|
-
function validateIssuesData(parsed) {
|
|
570
|
-
if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
571
|
-
const obj = parsed;
|
|
572
|
-
if (obj.version === ISSUES_DATA_VERSION && Array.isArray(obj.issues)) {
|
|
573
|
-
return parsed;
|
|
574
|
-
}
|
|
575
|
-
return null;
|
|
576
|
-
}
|
|
577
|
-
function validateMetricsData(parsed) {
|
|
578
|
-
if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
579
|
-
const obj = parsed;
|
|
580
|
-
if (obj.version === 1 && Array.isArray(obj.endpoints)) {
|
|
581
|
-
return parsed;
|
|
582
|
-
}
|
|
583
|
-
return null;
|
|
584
|
-
}
|
|
585
|
-
var init_type_guards = __esm({
|
|
586
|
-
"src/utils/type-guards.ts"() {
|
|
587
|
-
"use strict";
|
|
588
|
-
init_config();
|
|
589
|
-
}
|
|
590
|
-
});
|
|
591
|
-
|
|
592
|
-
// src/utils/log.ts
|
|
593
|
-
function brakitWarn(message) {
|
|
594
|
-
process.stderr.write(`${PREFIX} ${message}
|
|
595
|
-
`);
|
|
596
|
-
}
|
|
597
|
-
function brakitDebug(message) {
|
|
598
|
-
if (process.env.DEBUG_BRAKIT) {
|
|
599
|
-
process.stderr.write(`${PREFIX}:debug ${message}
|
|
600
|
-
`);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
var PREFIX;
|
|
604
|
-
var init_log = __esm({
|
|
605
|
-
"src/utils/log.ts"() {
|
|
606
|
-
"use strict";
|
|
607
|
-
PREFIX = "[brakit]";
|
|
608
|
-
}
|
|
609
|
-
});
|
|
610
|
-
|
|
611
749
|
// src/instrument/adapters/shared.ts
|
|
612
750
|
import { createRequire } from "module";
|
|
613
751
|
function tryRequire(id) {
|
|
@@ -1845,29 +1983,25 @@ function createIngestHandler(services) {
|
|
|
1845
1983
|
const routeEvent = (event) => {
|
|
1846
1984
|
switch (event.type) {
|
|
1847
1985
|
case TIMELINE_FETCH:
|
|
1848
|
-
|
|
1986
|
+
bus.emit("telemetry:fetch", event.data);
|
|
1849
1987
|
break;
|
|
1850
1988
|
case TIMELINE_LOG:
|
|
1851
|
-
|
|
1989
|
+
bus.emit("telemetry:log", event.data);
|
|
1852
1990
|
break;
|
|
1853
1991
|
case TIMELINE_ERROR:
|
|
1854
|
-
|
|
1992
|
+
bus.emit("telemetry:error", event.data);
|
|
1855
1993
|
break;
|
|
1856
1994
|
case TIMELINE_QUERY:
|
|
1857
|
-
|
|
1995
|
+
bus.emit("telemetry:query", event.data);
|
|
1858
1996
|
break;
|
|
1859
1997
|
}
|
|
1860
1998
|
};
|
|
1861
|
-
const
|
|
1862
|
-
const fetchStore = services.fetchStore;
|
|
1863
|
-
const logStore = services.logStore;
|
|
1864
|
-
const errorStore = services.errorStore;
|
|
1865
|
-
const requestStore = services.requestStore;
|
|
1999
|
+
const { bus, requestStore } = services;
|
|
1866
2000
|
const stores = {
|
|
1867
|
-
addQuery: (data) =>
|
|
1868
|
-
addFetch: (data) =>
|
|
1869
|
-
addLog: (data) =>
|
|
1870
|
-
addError: (data) =>
|
|
2001
|
+
addQuery: (data) => bus.emit("telemetry:query", data),
|
|
2002
|
+
addFetch: (data) => bus.emit("telemetry:fetch", data),
|
|
2003
|
+
addLog: (data) => bus.emit("telemetry:log", data),
|
|
2004
|
+
addError: (data) => bus.emit("telemetry:error", data),
|
|
1871
2005
|
addRequest: (data) => requestStore.add(data)
|
|
1872
2006
|
};
|
|
1873
2007
|
return (req, res) => {
|
|
@@ -2426,7 +2560,7 @@ var init_issue_store = __esm({
|
|
|
2426
2560
|
existing.occurrences++;
|
|
2427
2561
|
existing.issue = issue;
|
|
2428
2562
|
existing.cleanHitsSinceLastSeen = 0;
|
|
2429
|
-
if (existing.state === "resolved" || existing.state === "stale") {
|
|
2563
|
+
if (existing.aiStatus !== "wont_fix" && (existing.state === "resolved" || existing.state === "stale")) {
|
|
2430
2564
|
existing.state = "regressed";
|
|
2431
2565
|
existing.resolvedAt = null;
|
|
2432
2566
|
}
|
|
@@ -2452,10 +2586,11 @@ var init_issue_store = __esm({
|
|
|
2452
2586
|
return stateful;
|
|
2453
2587
|
}
|
|
2454
2588
|
/**
|
|
2455
|
-
*
|
|
2456
|
-
*
|
|
2457
|
-
*
|
|
2458
|
-
*
|
|
2589
|
+
* Evidence-based reconciliation: for each active issue whose endpoint had
|
|
2590
|
+
* traffic but the issue was NOT re-detected, increment cleanHitsSinceLastSeen.
|
|
2591
|
+
* After CLEAN_HITS_FOR_RESOLUTION consecutive clean cycles, auto-resolve.
|
|
2592
|
+
* Issues on endpoints with no recent traffic are marked stale after STALE_ISSUE_TTL_MS.
|
|
2593
|
+
* Resolved and stale issues are pruned after their respective TTLs expire.
|
|
2459
2594
|
*/
|
|
2460
2595
|
reconcile(currentIssueIds, activeEndpoints) {
|
|
2461
2596
|
const now = Date.now();
|
|
@@ -2605,11 +2740,22 @@ var init_project = __esm({
|
|
|
2605
2740
|
"use strict";
|
|
2606
2741
|
init_fs();
|
|
2607
2742
|
FRAMEWORKS = [
|
|
2743
|
+
// Meta-frameworks first (they bundle Express/Vite internally)
|
|
2608
2744
|
{ name: "nextjs", dep: "next", devCmd: "next dev", bin: "next", defaultPort: 3e3, devArgs: ["dev", "--port"] },
|
|
2609
2745
|
{ name: "remix", dep: "@remix-run/dev", devCmd: "remix dev", bin: "remix", defaultPort: 3e3, devArgs: ["dev"] },
|
|
2610
2746
|
{ name: "nuxt", dep: "nuxt", devCmd: "nuxt dev", bin: "nuxt", defaultPort: 3e3, devArgs: ["dev", "--port"] },
|
|
2611
|
-
{ name: "
|
|
2612
|
-
{ name: "
|
|
2747
|
+
{ name: "astro", dep: "astro", devCmd: "astro dev", bin: "astro", defaultPort: 4321, devArgs: ["dev", "--port"] },
|
|
2748
|
+
{ name: "nestjs", dep: "@nestjs/core", devCmd: "nest start", bin: "nest", defaultPort: 3e3, devArgs: ["--watch"] },
|
|
2749
|
+
{ name: "adonis", dep: "@adonisjs/core", devCmd: "node ace serve", bin: "ace", defaultPort: 3333, devArgs: ["serve", "--watch"] },
|
|
2750
|
+
{ name: "sails", dep: "sails", devCmd: "sails lift", bin: "sails", defaultPort: 1337, devArgs: ["lift"] },
|
|
2751
|
+
// Server frameworks
|
|
2752
|
+
{ name: "hono", dep: "hono", devCmd: "node", bin: "node", defaultPort: 3e3 },
|
|
2753
|
+
{ name: "fastify", dep: "fastify", devCmd: "node", bin: "node", defaultPort: 3e3 },
|
|
2754
|
+
{ name: "koa", dep: "koa", devCmd: "node", bin: "node", defaultPort: 3e3 },
|
|
2755
|
+
{ name: "hapi", dep: "@hapi/hapi", devCmd: "node", bin: "node", defaultPort: 3e3 },
|
|
2756
|
+
{ name: "express", dep: "express", devCmd: "node", bin: "node", defaultPort: 3e3 },
|
|
2757
|
+
// Bundlers (last — likely used alongside a framework above)
|
|
2758
|
+
{ name: "vite", dep: "vite", devCmd: "vite", bin: "vite", defaultPort: 5173, devArgs: ["--port"] }
|
|
2613
2759
|
];
|
|
2614
2760
|
}
|
|
2615
2761
|
});
|
|
@@ -4235,7 +4381,7 @@ var init_src = __esm({
|
|
|
4235
4381
|
init_engine();
|
|
4236
4382
|
init_insights2();
|
|
4237
4383
|
init_insights();
|
|
4238
|
-
VERSION = "0.10.
|
|
4384
|
+
VERSION = "0.10.1";
|
|
4239
4385
|
}
|
|
4240
4386
|
});
|
|
4241
4387
|
|
|
@@ -4255,7 +4401,10 @@ function getBaseStyles() {
|
|
|
4255
4401
|
--red:#dc2626;
|
|
4256
4402
|
--cyan:#0891b2;
|
|
4257
4403
|
--green-bg:rgba(22,163,74,0.08);--green-bg-subtle:rgba(22,163,74,0.05);--green-border:rgba(22,163,74,0.2);--green-border-subtle:rgba(22,163,74,0.15);
|
|
4258
|
-
--amber-bg:rgba(217,119,6,0.
|
|
4404
|
+
--amber-bg:rgba(217,119,6,0.08);--amber-border:rgba(217,119,6,0.15);
|
|
4405
|
+
--red-bg:rgba(220,38,38,0.08);--red-border:rgba(220,38,38,0.2);
|
|
4406
|
+
--blue-bg:rgba(37,99,235,0.08);--cyan-bg:rgba(8,145,178,0.07);
|
|
4407
|
+
--accent-bg:rgba(99,102,241,0.08);
|
|
4259
4408
|
--sidebar-width:232px;--header-height:52px;
|
|
4260
4409
|
--radius:8px;--radius-sm:6px;
|
|
4261
4410
|
--shadow-sm:0 1px 3px rgba(0,0,0,0.06),0 1px 2px rgba(0,0,0,0.03);
|
|
@@ -4312,6 +4461,7 @@ function getLayoutStyles() {
|
|
|
4312
4461
|
.sidebar-logo .logo-version{font-weight:400;font-size:11px;color:var(--text-muted);margin-left:8px;letter-spacing:0}
|
|
4313
4462
|
.sidebar-nav{padding:12px;flex:1}
|
|
4314
4463
|
.sidebar-section{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.8px;color:var(--text-muted);padding:16px 12px 8px}
|
|
4464
|
+
.sidebar-divider{height:1px;background:var(--border-subtle);margin:8px 12px}
|
|
4315
4465
|
.sidebar-item{display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:var(--radius);color:var(--text-dim);font-size:14px;font-weight:500;cursor:pointer;transition:all .15s;border:none;background:transparent;width:100%;text-align:left;font-family:var(--sans)}
|
|
4316
4466
|
.sidebar-item:hover{background:var(--bg-hover);color:var(--text)}
|
|
4317
4467
|
.sidebar-item.active{background:var(--bg-active);color:var(--accent)}
|
|
@@ -4345,7 +4495,7 @@ function getLayoutStyles() {
|
|
|
4345
4495
|
/* Content */
|
|
4346
4496
|
.main-content{flex:1;overflow-y:auto}
|
|
4347
4497
|
bk-dashboard{display:contents}
|
|
4348
|
-
bk-overview-view,bk-flows-view,bk-requests-view,bk-fetches-view,bk-queries-view,bk-errors-view,bk-logs-view,bk-security-view,bk-performance-view,bk-timeline-panel,bk-empty-state{display:block}
|
|
4498
|
+
bk-overview-view,bk-flows-view,bk-requests-view,bk-fetches-view,bk-queries-view,bk-errors-view,bk-logs-view,bk-security-view,bk-performance-view,bk-explorer-view,bk-insights-view,bk-timeline-panel,bk-empty-state{display:block}
|
|
4349
4499
|
bk-graph-view{display:block}
|
|
4350
4500
|
bk-method-badge,bk-status-pill,bk-duration-label,bk-copy-button{display:inline-flex;flex-shrink:0}
|
|
4351
4501
|
bk-stat-card{display:inline-flex}
|
|
@@ -4732,53 +4882,25 @@ var init_graph2 = __esm({
|
|
|
4732
4882
|
// src/dashboard/styles/overview.ts
|
|
4733
4883
|
function getOverviewStyles() {
|
|
4734
4884
|
return `
|
|
4735
|
-
|
|
4736
|
-
.ov-container{padding:24px 28px}
|
|
4737
|
-
|
|
4738
|
-
/* Summary banner */
|
|
4739
|
-
.ov-summary{display:flex;gap:10px;margin-bottom:24px;flex-wrap:wrap}
|
|
4740
|
-
.ov-stat{display:flex;flex-direction:column;gap:4px;flex:1;min-width:100px;padding:16px 18px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow-sm);transition:box-shadow var(--transition, .15s ease)}
|
|
4741
|
-
.ov-stat:hover{box-shadow:var(--shadow-md)}
|
|
4742
|
-
.ov-stat-value{font-size:22px;font-weight:700;font-family:var(--mono);color:var(--text);line-height:1.2}
|
|
4743
|
-
.ov-stat-label{font-size:10px;text-transform:uppercase;letter-spacing:.8px;color:var(--text-muted);font-weight:600}
|
|
4744
|
-
|
|
4745
|
-
/* Section header */
|
|
4746
|
-
.ov-section-title{font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.8px;color:var(--text-muted);margin-bottom:12px;display:flex;align-items:center;gap:8px}
|
|
4747
|
-
.ov-issue-count{font-size:11px;font-family:var(--mono);color:var(--text-dim);background:var(--bg-muted);border:1px solid var(--border);padding:1px 8px;border-radius:10px}
|
|
4748
|
-
|
|
4749
|
-
/* Insight cards */
|
|
4750
|
-
.ov-cards{display:flex;flex-direction:column;gap:8px}
|
|
4751
|
-
.ov-card{display:flex;align-items:flex-start;gap:14px;padding:16px 20px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;transition:all var(--transition, .15s ease);box-shadow:var(--shadow-sm)}
|
|
4752
|
-
.ov-card:hover{background:var(--bg-hover);border-color:var(--border-light);box-shadow:var(--shadow-md);transform:translateY(-1px)}
|
|
4753
|
-
.ov-card-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:10px;border-radius:50%;margin-top:2px}
|
|
4754
|
-
.ov-card-icon.critical{background:rgba(220,38,38,.08);color:var(--red)}
|
|
4755
|
-
.ov-card-icon.warning{background:rgba(217,119,6,.08);color:var(--amber)}
|
|
4756
|
-
.ov-card-icon.info{background:rgba(37,99,235,.08);color:var(--blue)}
|
|
4757
|
-
.ov-card-icon.resolved{background:var(--green-bg);color:var(--green)}
|
|
4758
|
-
.ov-card-body{flex:1;min-width:0}
|
|
4759
|
-
.ov-card-title{font-size:13px;font-weight:600;color:var(--text);margin-bottom:2px}
|
|
4760
|
-
.ov-card-desc{font-size:12px;color:var(--text-dim);line-height:1.5}
|
|
4761
|
-
.ov-card-detail{font-size:11px;font-family:var(--mono);color:var(--text-muted);margin-top:6px;padding:8px 10px;background:var(--bg-muted);border:1px solid var(--border-subtle);border-radius:var(--radius-sm);line-height:1.5}
|
|
4762
|
-
.ov-card-desc strong{color:var(--text);font-family:var(--mono);font-weight:600}
|
|
4763
|
-
.ov-card-arrow{color:var(--text-muted);font-size:12px;flex-shrink:0;margin-top:2px;font-family:var(--mono);transition:transform .15s}
|
|
4764
|
-
|
|
4765
|
-
/* Expanded card */
|
|
4766
|
-
.ov-card.expanded{border-color:var(--border-light);box-shadow:var(--shadow-md)}
|
|
4767
|
-
.ov-card-expand{display:none;margin-top:10px;padding-top:10px;border-top:1px solid var(--border)}
|
|
4768
|
-
.ov-card-hint{font-size:12px;color:var(--text-dim);line-height:1.5;margin-bottom:10px}
|
|
4769
|
-
.ov-card-link{font-size:12px;font-weight:600;color:var(--blue);cursor:pointer;display:inline-block;padding:4px 0}
|
|
4770
|
-
.ov-card-link:hover{text-decoration:underline}
|
|
4771
|
-
.ov-detail-label{font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}
|
|
4772
|
-
.ov-detail-item{font-size:12px;color:var(--text);font-family:var(--mono);padding:2px 0}
|
|
4773
|
-
|
|
4774
|
-
/* All-clear banner */
|
|
4775
|
-
.ov-clear{display:flex;align-items:center;gap:12px;padding:16px 20px;background:var(--green-bg-subtle);border:1px solid var(--green-border);border-radius:var(--radius);color:var(--green);font-size:13px;font-weight:500}
|
|
4776
|
-
.ov-clear-icon{font-size:16px}
|
|
4885
|
+
.ov-container{padding:28px}
|
|
4777
4886
|
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
.ov-card-
|
|
4781
|
-
.ov-card-
|
|
4887
|
+
.ov-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}
|
|
4888
|
+
|
|
4889
|
+
.ov-card-nav{display:flex;align-items:center;gap:16px;padding:20px 24px;background:var(--bg-card);border:1px solid var(--border);border-radius:12px;cursor:pointer;transition:all .18s ease;box-shadow:0 1px 3px rgba(0,0,0,.04)}
|
|
4890
|
+
.ov-card-nav:hover{border-color:var(--border-light);box-shadow:0 4px 16px rgba(0,0,0,.06);transform:translateY(-2px)}
|
|
4891
|
+
.ov-card-nav:active{transform:translateY(0)}
|
|
4892
|
+
|
|
4893
|
+
.ov-card-empty{opacity:.55}
|
|
4894
|
+
.ov-card-empty:hover{opacity:.8}
|
|
4895
|
+
|
|
4896
|
+
.ov-card-icon-lg{font-size:22px;width:40px;height:40px;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--bg-muted);border-radius:10px;color:var(--text-muted)}
|
|
4897
|
+
|
|
4898
|
+
.ov-card-content{flex:1;min-width:0}
|
|
4899
|
+
.ov-card-headline{font-size:16px;font-weight:700;color:var(--text);font-family:var(--mono);line-height:1.3}
|
|
4900
|
+
.ov-card-context{font-size:12px;color:var(--text-muted);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
4901
|
+
|
|
4902
|
+
.ov-card-arrow{font-size:16px;color:var(--text-muted);opacity:0;transition:opacity .15s,transform .15s;flex-shrink:0}
|
|
4903
|
+
.ov-card-nav:hover .ov-card-arrow{opacity:1;transform:translateX(2px)}
|
|
4782
4904
|
`;
|
|
4783
4905
|
}
|
|
4784
4906
|
var init_overview = __esm({
|
|
@@ -5172,9 +5294,93 @@ var init_graph_view = __esm({
|
|
|
5172
5294
|
}
|
|
5173
5295
|
});
|
|
5174
5296
|
|
|
5297
|
+
// src/dashboard/styles/explorer.ts
|
|
5298
|
+
function getExplorerStyles() {
|
|
5299
|
+
return `
|
|
5300
|
+
/* Explorer sub-tabs */
|
|
5301
|
+
.explorer-tabs{display:flex;gap:0;border-bottom:1px solid var(--border);padding:0 28px;background:var(--bg);position:sticky;top:0;z-index:2}
|
|
5302
|
+
.explorer-tab{padding:10px 16px;font-size:13px;font-weight:500;color:var(--text-muted);background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;transition:all .15s;display:flex;align-items:center;gap:6px;font-family:var(--sans);white-space:nowrap}
|
|
5303
|
+
.explorer-tab:hover{color:var(--text)}
|
|
5304
|
+
.explorer-tab.active{color:var(--accent);border-bottom-color:var(--accent)}
|
|
5305
|
+
.explorer-tab-count{font-size:11px;font-family:var(--mono);color:var(--text-muted);background:var(--bg-muted);padding:1px 6px;border-radius:8px}
|
|
5306
|
+
.explorer-tab.active .explorer-tab-count{color:var(--accent);background:var(--accent-bg)}
|
|
5307
|
+
`;
|
|
5308
|
+
}
|
|
5309
|
+
var init_explorer = __esm({
|
|
5310
|
+
"src/dashboard/styles/explorer.ts"() {
|
|
5311
|
+
"use strict";
|
|
5312
|
+
}
|
|
5313
|
+
});
|
|
5314
|
+
|
|
5315
|
+
// src/dashboard/styles/insights.ts
|
|
5316
|
+
function getInsightsStyles() {
|
|
5317
|
+
return `
|
|
5318
|
+
/* Insights filter chips */
|
|
5319
|
+
.insights-filters{display:flex;gap:6px;padding:16px 28px;border-bottom:1px solid var(--border);background:var(--bg);position:sticky;top:0;z-index:2}
|
|
5320
|
+
.insights-chip{font-size:12px;font-weight:500;padding:5px 14px;border:1px solid var(--border);border-radius:20px;background:var(--bg);color:var(--text-muted);cursor:pointer;transition:all .15s;display:flex;align-items:center;gap:5px;font-family:var(--sans)}
|
|
5321
|
+
.insights-chip:hover{border-color:var(--text-muted);color:var(--text)}
|
|
5322
|
+
.insights-chip.active{background:var(--accent);color:white;border-color:var(--accent)}
|
|
5323
|
+
.insights-chip-count{font-size:10px;font-family:var(--mono);background:rgba(0,0,0,.08);padding:1px 5px;border-radius:8px}
|
|
5324
|
+
.insights-chip.active .insights-chip-count{background:rgba(255,255,255,.25)}
|
|
5325
|
+
|
|
5326
|
+
/* Insights card list */
|
|
5327
|
+
.insights-list{padding:16px 28px}
|
|
5328
|
+
|
|
5329
|
+
.insights-empty{display:flex;align-items:center;gap:10px;padding:24px;color:var(--green);font-size:14px;font-weight:500}
|
|
5330
|
+
.insights-empty-icon{font-size:18px}
|
|
5331
|
+
|
|
5332
|
+
.insights-card{display:flex;align-items:flex-start;gap:12px;padding:14px 18px;background:var(--bg-card);border:1px solid var(--border);border-radius:10px;cursor:pointer;transition:all .15s;margin-bottom:8px}
|
|
5333
|
+
.insights-card:hover{border-color:var(--border-light);box-shadow:0 2px 8px rgba(0,0,0,.04)}
|
|
5334
|
+
.insights-card.expanded{border-color:var(--border-light);box-shadow:0 2px 8px rgba(0,0,0,.04)}
|
|
5335
|
+
.insights-card.resolved{opacity:.55}
|
|
5336
|
+
.insights-card.resolved:hover{opacity:.8}
|
|
5337
|
+
|
|
5338
|
+
.insights-card-left{flex-shrink:0;padding-top:2px}
|
|
5339
|
+
.insights-sev{width:22px;height:22px;display:flex;align-items:center;justify-content:center;font-size:10px;border-radius:50%}
|
|
5340
|
+
.insights-sev.critical{background:var(--red-bg);color:var(--red)}
|
|
5341
|
+
.insights-sev.warning{background:var(--amber-bg);color:var(--amber)}
|
|
5342
|
+
.insights-sev.info{background:var(--blue-bg);color:var(--blue)}
|
|
5343
|
+
|
|
5344
|
+
.insights-card-body{flex:1;min-width:0}
|
|
5345
|
+
.insights-card-header{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:3px}
|
|
5346
|
+
.insights-card-title{font-size:13px;font-weight:600;color:var(--text)}
|
|
5347
|
+
.insights-card-title.resolved{text-decoration:line-through;color:var(--text-muted)}
|
|
5348
|
+
.insights-card-cat{font-size:9px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--text-muted);background:var(--bg-muted);padding:1px 6px;border-radius:4px}
|
|
5349
|
+
.insights-card-count{font-size:11px;font-family:var(--mono);color:var(--text-muted)}
|
|
5350
|
+
.insights-card-desc{font-size:12px;color:var(--text-dim);line-height:1.5}
|
|
5351
|
+
.insights-card-detail{font-size:11px;font-family:var(--mono);color:var(--text-muted);margin-top:6px;padding:6px 10px;background:var(--bg-muted);border:1px solid var(--border-subtle);border-radius:6px;line-height:1.5}
|
|
5352
|
+
.insights-card-progress{font-size:11px;color:var(--text-muted);margin-top:4px;font-family:var(--mono)}
|
|
5353
|
+
.insights-card-hint{font-size:12px;color:var(--text-dim);line-height:1.6;margin-top:8px;padding-top:8px;border-top:1px solid var(--border)}
|
|
5354
|
+
|
|
5355
|
+
.insights-badge-regressed{font-size:9px;font-weight:700;color:var(--red);background:var(--red-bg);padding:1px 6px;border-radius:4px}
|
|
5356
|
+
.insights-badge-verifying{font-size:9px;font-weight:700;color:var(--amber);background:var(--amber-bg);padding:1px 6px;border-radius:4px}
|
|
5357
|
+
.insights-badge-resolved{font-size:9px;font-weight:700;color:var(--green);background:var(--green-bg);padding:1px 6px;border-radius:4px}
|
|
5358
|
+
|
|
5359
|
+
.insights-card-arrow{color:var(--text-muted);font-size:12px;flex-shrink:0;padding-top:2px;font-family:var(--mono);transition:transform .15s}
|
|
5360
|
+
|
|
5361
|
+
.insights-section{display:flex;align-items:center;gap:8px;padding:14px 0 8px;margin-top:4px;font-size:12px;font-weight:700;color:var(--text);text-transform:uppercase;letter-spacing:.5px;border-top:1px solid var(--border);user-select:none}
|
|
5362
|
+
.insights-section:first-child{border-top:none;margin-top:0}
|
|
5363
|
+
.insights-section-icon{font-size:11px;width:16px;text-align:center}
|
|
5364
|
+
.insights-section-count{font-size:11px;font-family:var(--mono);color:var(--text-muted);background:var(--bg-muted);padding:1px 7px;border-radius:8px;font-weight:500}
|
|
5365
|
+
.insights-section-regressed{color:var(--red)}
|
|
5366
|
+
.insights-section-regressed .insights-section-count{color:var(--red);background:var(--red-bg)}
|
|
5367
|
+
.insights-section-verifying{color:var(--amber)}
|
|
5368
|
+
.insights-section-verifying .insights-section-count{color:var(--amber);background:var(--amber-bg)}
|
|
5369
|
+
.insights-section-resolved{color:var(--green)}
|
|
5370
|
+
.insights-section-resolved .insights-section-count{color:var(--green);background:var(--green-bg)}
|
|
5371
|
+
.insights-section-dismissed{color:var(--text-muted);cursor:pointer}
|
|
5372
|
+
.insights-section-dismissed:hover{color:var(--text)}
|
|
5373
|
+
`;
|
|
5374
|
+
}
|
|
5375
|
+
var init_insights3 = __esm({
|
|
5376
|
+
"src/dashboard/styles/insights.ts"() {
|
|
5377
|
+
"use strict";
|
|
5378
|
+
}
|
|
5379
|
+
});
|
|
5380
|
+
|
|
5175
5381
|
// src/dashboard/styles.ts
|
|
5176
5382
|
function getStyles() {
|
|
5177
|
-
return getBaseStyles() + getLayoutStyles() + getFlowStyles() + getRequestStyles() + getPerformanceStyles() + getOverviewStyles() + getSecurityStyles() + getTimelineStyles() + getGraphViewStyles();
|
|
5383
|
+
return getBaseStyles() + getLayoutStyles() + getFlowStyles() + getRequestStyles() + getPerformanceStyles() + getOverviewStyles() + getSecurityStyles() + getTimelineStyles() + getGraphViewStyles() + getExplorerStyles() + getInsightsStyles();
|
|
5178
5384
|
}
|
|
5179
5385
|
var init_styles = __esm({
|
|
5180
5386
|
"src/dashboard/styles.ts"() {
|
|
@@ -5188,6 +5394,8 @@ var init_styles = __esm({
|
|
|
5188
5394
|
init_security2();
|
|
5189
5395
|
init_timeline();
|
|
5190
5396
|
init_graph_view();
|
|
5397
|
+
init_explorer();
|
|
5398
|
+
init_insights3();
|
|
5191
5399
|
}
|
|
5192
5400
|
});
|
|
5193
5401
|
|
|
@@ -5435,8 +5643,8 @@ function trackSession(services) {
|
|
|
5435
5643
|
tabs_viewed: [...session.tabsViewed],
|
|
5436
5644
|
dashboard_opened: session.dashboardOpened,
|
|
5437
5645
|
explain_used: session.explainUsed,
|
|
5438
|
-
session_duration_s: Math.
|
|
5439
|
-
|
|
5646
|
+
session_duration_s: Math.ceil((now - session.startTime) / 1e3),
|
|
5647
|
+
session_duration_ms: now - session.startTime,
|
|
5440
5648
|
setup_succeeded: session.setupSucceeded,
|
|
5441
5649
|
setup_duration_ms: session.setupDurationMs,
|
|
5442
5650
|
framework_detection_candidates: session.frameworkCandidates,
|
|
@@ -6729,6 +6937,7 @@ function startTerminalInsights(services, proxyPort) {
|
|
|
6729
6937
|
const resolvedLines = [];
|
|
6730
6938
|
const regressedLines = [];
|
|
6731
6939
|
for (const si of issues) {
|
|
6940
|
+
if (si.aiStatus === "wont_fix") continue;
|
|
6732
6941
|
if (si.state === "resolved") {
|
|
6733
6942
|
if (resolvedKeys.has(si.issueId)) continue;
|
|
6734
6943
|
resolvedKeys.add(si.issueId);
|
|
@@ -6873,125 +7082,6 @@ var init_guard = __esm({
|
|
|
6873
7082
|
}
|
|
6874
7083
|
});
|
|
6875
7084
|
|
|
6876
|
-
// src/runtime/capture.ts
|
|
6877
|
-
import { gunzip, brotliDecompress, inflate } from "zlib";
|
|
6878
|
-
function outgoingToIncoming(headers2) {
|
|
6879
|
-
const result = {};
|
|
6880
|
-
for (const [key, value] of Object.entries(headers2)) {
|
|
6881
|
-
if (value === void 0) continue;
|
|
6882
|
-
if (Array.isArray(value)) {
|
|
6883
|
-
result[key] = value.map(String);
|
|
6884
|
-
} else {
|
|
6885
|
-
result[key] = String(value);
|
|
6886
|
-
}
|
|
6887
|
-
}
|
|
6888
|
-
return result;
|
|
6889
|
-
}
|
|
6890
|
-
function getDecompressor(encoding) {
|
|
6891
|
-
if (encoding === CONTENT_ENCODING_GZIP) return gunzip;
|
|
6892
|
-
if (encoding === CONTENT_ENCODING_BR) return brotliDecompress;
|
|
6893
|
-
if (encoding === CONTENT_ENCODING_DEFLATE) return inflate;
|
|
6894
|
-
return null;
|
|
6895
|
-
}
|
|
6896
|
-
function decompressAsync(body, encoding) {
|
|
6897
|
-
const decompressor = getDecompressor(encoding);
|
|
6898
|
-
if (!decompressor) return Promise.resolve(body);
|
|
6899
|
-
return new Promise((resolve6) => {
|
|
6900
|
-
decompressor(body, (err, result) => {
|
|
6901
|
-
resolve6(err ? body : result);
|
|
6902
|
-
});
|
|
6903
|
-
});
|
|
6904
|
-
}
|
|
6905
|
-
function toBuffer(chunk) {
|
|
6906
|
-
if (Buffer.isBuffer(chunk)) return chunk;
|
|
6907
|
-
if (chunk instanceof Uint8Array) return Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
6908
|
-
if (typeof chunk === "string") return Buffer.from(chunk);
|
|
6909
|
-
return null;
|
|
6910
|
-
}
|
|
6911
|
-
function captureInProcess(req, res, requestId, requestStore, isChild = false) {
|
|
6912
|
-
const startTime = performance.now();
|
|
6913
|
-
const method = req.method ?? "GET";
|
|
6914
|
-
const resChunks = [];
|
|
6915
|
-
let resSize = 0;
|
|
6916
|
-
const originalWrite = res.write;
|
|
6917
|
-
const originalEnd = res.end;
|
|
6918
|
-
let truncated = false;
|
|
6919
|
-
res.write = function(...args) {
|
|
6920
|
-
try {
|
|
6921
|
-
const chunk = args[0];
|
|
6922
|
-
if (chunk != null && typeof chunk !== "function") {
|
|
6923
|
-
if (resSize < DEFAULT_MAX_BODY_CAPTURE) {
|
|
6924
|
-
const buf = toBuffer(chunk);
|
|
6925
|
-
if (buf) {
|
|
6926
|
-
resChunks.push(buf);
|
|
6927
|
-
resSize += buf.length;
|
|
6928
|
-
}
|
|
6929
|
-
} else {
|
|
6930
|
-
truncated = true;
|
|
6931
|
-
}
|
|
6932
|
-
}
|
|
6933
|
-
} catch (e) {
|
|
6934
|
-
brakitDebug(`capture write: ${getErrorMessage(e)}`);
|
|
6935
|
-
}
|
|
6936
|
-
return originalWrite.apply(this, args);
|
|
6937
|
-
};
|
|
6938
|
-
res.end = function(...args) {
|
|
6939
|
-
try {
|
|
6940
|
-
const chunk = typeof args[0] !== "function" ? args[0] : void 0;
|
|
6941
|
-
if (chunk != null && resSize < DEFAULT_MAX_BODY_CAPTURE) {
|
|
6942
|
-
const buf = toBuffer(chunk);
|
|
6943
|
-
if (buf) {
|
|
6944
|
-
resChunks.push(buf);
|
|
6945
|
-
}
|
|
6946
|
-
}
|
|
6947
|
-
} catch (e) {
|
|
6948
|
-
brakitDebug(`capture end: ${getErrorMessage(e)}`);
|
|
6949
|
-
}
|
|
6950
|
-
const result = originalEnd.apply(this, args);
|
|
6951
|
-
const endTime = performance.now();
|
|
6952
|
-
const encoding = String(res.getHeader("content-encoding") ?? "").toLowerCase();
|
|
6953
|
-
const statusCode = res.statusCode;
|
|
6954
|
-
const responseHeaders = outgoingToIncoming(res.getHeaders());
|
|
6955
|
-
const responseContentType = String(res.getHeader("content-type") ?? "");
|
|
6956
|
-
const capturedChunks = resChunks.slice();
|
|
6957
|
-
if (!isChild) {
|
|
6958
|
-
void (async () => {
|
|
6959
|
-
try {
|
|
6960
|
-
let body = capturedChunks.length > 0 ? Buffer.concat(capturedChunks) : null;
|
|
6961
|
-
if (body && encoding && !truncated) {
|
|
6962
|
-
body = await decompressAsync(body, encoding);
|
|
6963
|
-
}
|
|
6964
|
-
requestStore.capture({
|
|
6965
|
-
requestId,
|
|
6966
|
-
method,
|
|
6967
|
-
url: req.url ?? "/",
|
|
6968
|
-
requestHeaders: req.headers,
|
|
6969
|
-
requestBody: null,
|
|
6970
|
-
statusCode,
|
|
6971
|
-
responseHeaders,
|
|
6972
|
-
responseBody: body,
|
|
6973
|
-
responseContentType,
|
|
6974
|
-
startTime,
|
|
6975
|
-
endTime,
|
|
6976
|
-
config: { maxBodyCapture: DEFAULT_MAX_BODY_CAPTURE }
|
|
6977
|
-
});
|
|
6978
|
-
} catch (e) {
|
|
6979
|
-
brakitDebug(`capture store: ${getErrorMessage(e)}`);
|
|
6980
|
-
}
|
|
6981
|
-
})();
|
|
6982
|
-
}
|
|
6983
|
-
return result;
|
|
6984
|
-
};
|
|
6985
|
-
}
|
|
6986
|
-
var init_capture = __esm({
|
|
6987
|
-
"src/runtime/capture.ts"() {
|
|
6988
|
-
"use strict";
|
|
6989
|
-
init_constants();
|
|
6990
|
-
init_log();
|
|
6991
|
-
init_type_guards();
|
|
6992
|
-
}
|
|
6993
|
-
});
|
|
6994
|
-
|
|
6995
7085
|
// src/runtime/interceptor.ts
|
|
6996
7086
|
import http from "http";
|
|
6997
7087
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
@@ -7177,7 +7267,8 @@ function registerLifecycle(allServices, stores, services, cwd) {
|
|
|
7177
7267
|
process.on("SIGTERM", () => {
|
|
7178
7268
|
recordExitReason(EXIT_REASON_SIGTERM);
|
|
7179
7269
|
});
|
|
7180
|
-
process.on("beforeExit", () => {
|
|
7270
|
+
process.on("beforeExit", async () => {
|
|
7271
|
+
await drainPendingCaptures();
|
|
7181
7272
|
recordExitReason(EXIT_REASON_CLEAN);
|
|
7182
7273
|
sendTelemetry();
|
|
7183
7274
|
});
|
|
@@ -7270,6 +7361,7 @@ var init_setup = __esm({
|
|
|
7270
7361
|
"src/runtime/setup.ts"() {
|
|
7271
7362
|
"use strict";
|
|
7272
7363
|
init_fetch();
|
|
7364
|
+
init_capture();
|
|
7273
7365
|
init_console();
|
|
7274
7366
|
init_errors();
|
|
7275
7367
|
init_adapters();
|