@oconde/radar 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +8 -0
- package/dist/{client-CZHtsQAd.d.cts → client-BB-to8cr.d.cts} +11 -0
- package/dist/{client-DbBsXgpj.d.ts → client-BS798K3S.d.ts} +11 -0
- package/dist/index.cjs +177 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +186 -23
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +177 -14
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.d.cts +1 -1
- package/dist/nest/index.d.ts +1 -1
- package/dist/nest/index.js +186 -23
- package/dist/nest/index.js.map +1 -1
- package/dist/sveltekit/index.cjs +179 -16
- package/dist/sveltekit/index.cjs.map +1 -1
- package/dist/sveltekit/index.d.cts +1 -1
- package/dist/sveltekit/index.d.ts +1 -1
- package/dist/sveltekit/index.js +190 -27
- package/dist/sveltekit/index.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Novo
|
|
6
|
+
|
|
7
|
+
- `traceFetch`: cada `fetch` de saída vira um log `http.client` com método, host, caminho (sem a query, com trechos que parecem segredo mascarados), status e duração, ou o erro com a causa (`fetch failed (ECONNREFUSED)`). Para os hosts de `propagateTo`, o SDK manda o `x-request-id` da requisição atual, sem trocar um que o app já tenha posto. Chamadas para o próprio Radar ficam de fora. Desligado por padrão.
|
|
8
|
+
|
|
9
|
+
### Correções
|
|
10
|
+
|
|
11
|
+
- O nome da função inferido do código original não se confunde mais com chaves e com a palavra `function` dentro de comentários de várias linhas (como os de JSDoc).
|
|
12
|
+
|
|
3
13
|
## 0.2.0
|
|
4
14
|
|
|
5
15
|
### Novo
|
package/README.md
CHANGED
|
@@ -98,6 +98,14 @@ await radar.cron('nightly-report', () => buildReport());
|
|
|
98
98
|
|
|
99
99
|
`radar.cron` avisa o Radar no início, no fim e na falha, e o Radar alerta se a tarefa atrasar ou falhar. Em scripts sem o SDK, o check-in é um `POST` (veja o [PROTOCOL.md](PROTOCOL.md)). Para jobs e workers, `radar.withContext(fn)` dá a cada execução o próprio `requestId`. Detalhes em [Tarefas agendadas](https://radar.oconde.dev/docs/sdk/cron/).
|
|
100
100
|
|
|
101
|
+
## Chamadas para outros serviços
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
radar.init({ key: process.env.RADAR_KEY, traceFetch: { propagateTo: ['api.spinlab.dev', '.oconde.dev'] } });
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Com `traceFetch`, cada `fetch` que o app faz vira um log `http.client` com método, host, caminho (sem a query, e com trechos que parecem token mascarados), status e duração, ou o erro quando a chamada nem chega a responder. Dentro de uma requisição, o log entra na linha do tempo dela. Para os hosts de `propagateTo` (o nome exato, `.dominio` para os subdomínios ou uma RegExp), o SDK manda o `x-request-id` da requisição atual, e o Radar mostra a mesma requisição nos dois projetos. `traceFetch: true` registra as chamadas sem mandar o id para ninguém. Chamadas para o próprio Radar ficam de fora.
|
|
108
|
+
|
|
101
109
|
## Erros com o seu código
|
|
102
110
|
|
|
103
111
|
Ligue no `tsconfig` para os erros mostrarem as linhas do TypeScript:
|
|
@@ -35,6 +35,14 @@ type RadarMiddleware = (req: RequestLike, res: ResponseLike, next: (error?: unkn
|
|
|
35
35
|
|
|
36
36
|
type RedactMode = 'mask' | 'none';
|
|
37
37
|
type RequestDetail = 'full' | 'route';
|
|
38
|
+
type FetchTraceTarget = string | RegExp;
|
|
39
|
+
type TraceFetchOption = boolean | {
|
|
40
|
+
propagateTo?: FetchTraceTarget[];
|
|
41
|
+
};
|
|
42
|
+
type ResolvedTraceFetch = {
|
|
43
|
+
enabled: boolean;
|
|
44
|
+
propagateTo: FetchTraceTarget[];
|
|
45
|
+
};
|
|
38
46
|
type RadarOptions = {
|
|
39
47
|
key?: string;
|
|
40
48
|
endpoint?: string;
|
|
@@ -48,6 +56,7 @@ type RadarOptions = {
|
|
|
48
56
|
logRequests?: boolean;
|
|
49
57
|
ignorePaths?: string[];
|
|
50
58
|
captureUnhandled?: boolean;
|
|
59
|
+
traceFetch?: TraceFetchOption;
|
|
51
60
|
debug?: boolean;
|
|
52
61
|
};
|
|
53
62
|
type ResolvedOptions = {
|
|
@@ -63,6 +72,7 @@ type ResolvedOptions = {
|
|
|
63
72
|
logRequests: boolean;
|
|
64
73
|
ignorePaths: string[];
|
|
65
74
|
captureUnhandled: boolean;
|
|
75
|
+
traceFetch: ResolvedTraceFetch;
|
|
66
76
|
debug: boolean;
|
|
67
77
|
};
|
|
68
78
|
|
|
@@ -95,6 +105,7 @@ declare class RadarClient {
|
|
|
95
105
|
private initialized;
|
|
96
106
|
private closed;
|
|
97
107
|
private readonly captured;
|
|
108
|
+
private restoreFetch;
|
|
98
109
|
get isEnabled(): boolean;
|
|
99
110
|
get settings(): Readonly<ResolvedOptions>;
|
|
100
111
|
init(options?: RadarOptions): void;
|
|
@@ -35,6 +35,14 @@ type RadarMiddleware = (req: RequestLike, res: ResponseLike, next: (error?: unkn
|
|
|
35
35
|
|
|
36
36
|
type RedactMode = 'mask' | 'none';
|
|
37
37
|
type RequestDetail = 'full' | 'route';
|
|
38
|
+
type FetchTraceTarget = string | RegExp;
|
|
39
|
+
type TraceFetchOption = boolean | {
|
|
40
|
+
propagateTo?: FetchTraceTarget[];
|
|
41
|
+
};
|
|
42
|
+
type ResolvedTraceFetch = {
|
|
43
|
+
enabled: boolean;
|
|
44
|
+
propagateTo: FetchTraceTarget[];
|
|
45
|
+
};
|
|
38
46
|
type RadarOptions = {
|
|
39
47
|
key?: string;
|
|
40
48
|
endpoint?: string;
|
|
@@ -48,6 +56,7 @@ type RadarOptions = {
|
|
|
48
56
|
logRequests?: boolean;
|
|
49
57
|
ignorePaths?: string[];
|
|
50
58
|
captureUnhandled?: boolean;
|
|
59
|
+
traceFetch?: TraceFetchOption;
|
|
51
60
|
debug?: boolean;
|
|
52
61
|
};
|
|
53
62
|
type ResolvedOptions = {
|
|
@@ -63,6 +72,7 @@ type ResolvedOptions = {
|
|
|
63
72
|
logRequests: boolean;
|
|
64
73
|
ignorePaths: string[];
|
|
65
74
|
captureUnhandled: boolean;
|
|
75
|
+
traceFetch: ResolvedTraceFetch;
|
|
66
76
|
debug: boolean;
|
|
67
77
|
};
|
|
68
78
|
|
|
@@ -95,6 +105,7 @@ declare class RadarClient {
|
|
|
95
105
|
private initialized;
|
|
96
106
|
private closed;
|
|
97
107
|
private readonly captured;
|
|
108
|
+
private restoreFetch;
|
|
98
109
|
get isEnabled(): boolean;
|
|
99
110
|
get settings(): Readonly<ResolvedOptions>;
|
|
100
111
|
init(options?: RadarOptions): void;
|
package/dist/index.cjs
CHANGED
|
@@ -282,7 +282,10 @@ function requestPath(req) {
|
|
|
282
282
|
}
|
|
283
283
|
function requestRoute(req, route) {
|
|
284
284
|
if (route) return route;
|
|
285
|
-
|
|
285
|
+
if (typeof req.route?.path !== "string") return void 0;
|
|
286
|
+
const base = typeof req.baseUrl === "string" ? req.baseUrl.replace(/\/+$/, "") : "";
|
|
287
|
+
if (!base) return req.route.path;
|
|
288
|
+
return req.route.path === "/" ? base : `${base}${req.route.path}`;
|
|
286
289
|
}
|
|
287
290
|
var ROUTE_PARAM = /^:([A-Za-z_$][\w$]*)/;
|
|
288
291
|
function pathSegments(value) {
|
|
@@ -416,6 +419,12 @@ function createMiddleware(logger) {
|
|
|
416
419
|
// src/options.ts
|
|
417
420
|
var DEFAULT_ENDPOINT = "https://radar-ingest.oconde.dev";
|
|
418
421
|
var LEVELS = ["debug", "info", "warn", "error"];
|
|
422
|
+
function resolveTraceFetch(value) {
|
|
423
|
+
if (!value) return { enabled: false, propagateTo: [] };
|
|
424
|
+
if (value === true) return { enabled: true, propagateTo: [] };
|
|
425
|
+
const targets2 = Array.isArray(value.propagateTo) ? value.propagateTo : [];
|
|
426
|
+
return { enabled: true, propagateTo: targets2.filter((target) => typeof target === "string" ? target.trim() !== "" : target instanceof RegExp) };
|
|
427
|
+
}
|
|
419
428
|
function resolveOptions(options = {}, env = process.env) {
|
|
420
429
|
const key = options.key?.trim() || void 0;
|
|
421
430
|
return {
|
|
@@ -431,6 +440,7 @@ function resolveOptions(options = {}, env = process.env) {
|
|
|
431
440
|
logRequests: options.logRequests ?? true,
|
|
432
441
|
ignorePaths: options.ignorePaths ?? ["/healthz", "/health"],
|
|
433
442
|
captureUnhandled: options.captureUnhandled ?? true,
|
|
443
|
+
traceFetch: resolveTraceFetch(options.traceFetch),
|
|
434
444
|
debug: options.debug ?? false
|
|
435
445
|
};
|
|
436
446
|
}
|
|
@@ -498,6 +508,7 @@ var IDENTIFIER = "[A-Za-z_$][\\w$]*";
|
|
|
498
508
|
var MAX_LINES_UP = 400;
|
|
499
509
|
var MAX_HEADER_LINES = 6;
|
|
500
510
|
var MAX_NAME_LENGTH = 100;
|
|
511
|
+
var MAX_COMMENT_LINES = 40;
|
|
501
512
|
var CONTROL_BLOCK = /^\s*(?:\}\s*)?(?:if|else|for|while|do|switch|try|catch|finally|with)\b/;
|
|
502
513
|
var CLASS_BODY = new RegExp(`\\bclass\\s+${IDENTIFIER}`);
|
|
503
514
|
var MARKUP_BOUNDARY = /<\/?(?:script|style|template)\b/i;
|
|
@@ -510,8 +521,58 @@ var NAME_PATTERNS = [
|
|
|
510
521
|
];
|
|
511
522
|
var METHOD_PATTERN = new RegExp(`^\\s*(?:(?:export|default|public|private|protected|static|async|override|readonly|get|set)\\s+)*\\*?\\s*(${IDENTIFIER})\\s*(?:<[^>]*>)?\\s*\\([^]*\\)\\s*(?::\\s*[^{]+)?$`);
|
|
512
523
|
var ANONYMOUS_FUNCTION = /\bfunction\b|=>/;
|
|
513
|
-
|
|
514
|
-
|
|
524
|
+
var STRING_LITERAL = /(["'`])(?:\\.|(?!\1)[^\\])*\1/g;
|
|
525
|
+
function lineCommentAt(text, from) {
|
|
526
|
+
for (let index = text.indexOf("//", from); index >= 0; index = text.indexOf("//", index + 1)) {
|
|
527
|
+
if (index === 0 || text[index - 1] !== ":") return index;
|
|
528
|
+
}
|
|
529
|
+
return -1;
|
|
530
|
+
}
|
|
531
|
+
function blockCommentAt(text, from) {
|
|
532
|
+
for (let index = text.indexOf("/*", from); index >= 0; index = text.indexOf("/*", index + 1)) {
|
|
533
|
+
if (index === 0 || text[index - 1] !== "\\") return index;
|
|
534
|
+
}
|
|
535
|
+
return -1;
|
|
536
|
+
}
|
|
537
|
+
function stripComments(text, insideComment, closesLater) {
|
|
538
|
+
let code = "";
|
|
539
|
+
let position = 0;
|
|
540
|
+
let inside = insideComment;
|
|
541
|
+
while (position < text.length) {
|
|
542
|
+
if (inside) {
|
|
543
|
+
const end = text.indexOf("*/", position);
|
|
544
|
+
if (end < 0) return { code, insideComment: true };
|
|
545
|
+
inside = false;
|
|
546
|
+
position = end + 2;
|
|
547
|
+
continue;
|
|
548
|
+
}
|
|
549
|
+
const block = blockCommentAt(text, position);
|
|
550
|
+
const line = lineCommentAt(text, position);
|
|
551
|
+
if (line >= 0 && (block < 0 || line < block)) return { code: code + text.slice(position, line), insideComment: false };
|
|
552
|
+
if (block < 0) return { code: code + text.slice(position), insideComment: false };
|
|
553
|
+
if (text.indexOf("*/", block + 2) < 0 && !closesLater()) {
|
|
554
|
+
code += text.slice(position, block + 2);
|
|
555
|
+
position = block + 2;
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
code += text.slice(position, block);
|
|
559
|
+
inside = true;
|
|
560
|
+
position = block + 2;
|
|
561
|
+
}
|
|
562
|
+
return { code, insideComment: inside };
|
|
563
|
+
}
|
|
564
|
+
function codeLines(lines, from, start, column) {
|
|
565
|
+
const plain = lines.slice(from, start + 1).map((line) => line.replace(STRING_LITERAL, '""'));
|
|
566
|
+
const closesWithin = (index) => plain.slice(index + 1, index + 1 + MAX_COMMENT_LINES).some((line) => line.includes("*/"));
|
|
567
|
+
const result = [];
|
|
568
|
+
let insideComment = false;
|
|
569
|
+
for (let index = 0; index < plain.length; index++) {
|
|
570
|
+
const text = index === plain.length - 1 && column ? (lines[start] ?? "").slice(0, Math.max(0, column - 1)).replace(STRING_LITERAL, '""') : plain[index] ?? "";
|
|
571
|
+
const stripped = stripComments(text, insideComment, () => closesWithin(index));
|
|
572
|
+
insideComment = stripped.insideComment;
|
|
573
|
+
result.push(stripped.code);
|
|
574
|
+
}
|
|
575
|
+
return result;
|
|
515
576
|
}
|
|
516
577
|
function parenBalance(text) {
|
|
517
578
|
let balance = 0;
|
|
@@ -521,11 +582,11 @@ function parenBalance(text) {
|
|
|
521
582
|
}
|
|
522
583
|
return balance;
|
|
523
584
|
}
|
|
524
|
-
function headerOf(
|
|
585
|
+
function headerOf(code, index, prefix) {
|
|
525
586
|
let header = prefix;
|
|
526
587
|
for (let previous = index - 1; previous >= 0 && previous >= index - MAX_HEADER_LINES; previous--) {
|
|
527
588
|
if (header.trim() !== "" && parenBalance(header) >= 0) break;
|
|
528
|
-
header = `${
|
|
589
|
+
header = `${code[previous] ?? ""} ${header}`;
|
|
529
590
|
}
|
|
530
591
|
return header;
|
|
531
592
|
}
|
|
@@ -540,11 +601,12 @@ function nameIn(header) {
|
|
|
540
601
|
function enclosingFunctionName(lines, line, column) {
|
|
541
602
|
const start = line - 1;
|
|
542
603
|
if (start < 0 || start >= lines.length) return void 0;
|
|
604
|
+
const from = Math.max(0, start - MAX_LINES_UP - MAX_HEADER_LINES);
|
|
605
|
+
const cleaned = codeLines(lines, from, start, column);
|
|
543
606
|
let depth = 0;
|
|
544
607
|
for (let index = start; index >= 0 && index >= start - MAX_LINES_UP; index--) {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
const code = codeOnly(index === start && column ? raw.slice(0, Math.max(0, column - 1)) : raw);
|
|
608
|
+
if (index < start && MARKUP_BOUNDARY.test(lines[index] ?? "")) return void 0;
|
|
609
|
+
const code = cleaned[index - from] ?? "";
|
|
548
610
|
for (let position = code.length - 1; position >= 0; position--) {
|
|
549
611
|
const char = code[position];
|
|
550
612
|
if (char === "}") {
|
|
@@ -554,7 +616,7 @@ function enclosingFunctionName(lines, line, column) {
|
|
|
554
616
|
depth -= 1;
|
|
555
617
|
continue;
|
|
556
618
|
}
|
|
557
|
-
const header = headerOf(
|
|
619
|
+
const header = headerOf(cleaned, index - from, code.slice(0, position));
|
|
558
620
|
if (CLASS_BODY.test(header)) return void 0;
|
|
559
621
|
if (CONTROL_BLOCK.test(header)) continue;
|
|
560
622
|
const name = nameIn(header);
|
|
@@ -796,10 +858,6 @@ function safeStringify(value) {
|
|
|
796
858
|
}
|
|
797
859
|
}
|
|
798
860
|
|
|
799
|
-
// src/transport.ts
|
|
800
|
-
var import_node_util2 = require("util");
|
|
801
|
-
var import_node_zlib = require("zlib");
|
|
802
|
-
|
|
803
861
|
// src/util.ts
|
|
804
862
|
var import_node_perf_hooks2 = require("perf_hooks");
|
|
805
863
|
function describeError(error) {
|
|
@@ -809,7 +867,101 @@ function elapsedSince(startedAt) {
|
|
|
809
867
|
return Math.round(import_node_perf_hooks2.performance.now() - startedAt);
|
|
810
868
|
}
|
|
811
869
|
|
|
870
|
+
// src/trace-fetch.ts
|
|
871
|
+
var WRAPPED = /* @__PURE__ */ Symbol.for("@oconde/radar.fetch");
|
|
872
|
+
var REQUEST_ID_HEADER = "x-request-id";
|
|
873
|
+
var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
874
|
+
var TELEGRAM_BOT = /^bot\d{5,}:[\w-]{20,}$/;
|
|
875
|
+
var TOKEN_LIKE = /^[\w\-.~+=]{20,}$/;
|
|
876
|
+
function secretSegment(segment) {
|
|
877
|
+
if (UUID.test(segment)) return false;
|
|
878
|
+
if (TELEGRAM_BOT.test(segment) || looksLikeCredential(segment)) return true;
|
|
879
|
+
return TOKEN_LIKE.test(segment) && /[A-Za-z]/.test(segment) && /\d/.test(segment);
|
|
880
|
+
}
|
|
881
|
+
function outboundPath(pathname, mode) {
|
|
882
|
+
if (mode === "none") return pathname;
|
|
883
|
+
return pathname.split("/").map((segment) => {
|
|
884
|
+
let decoded = segment;
|
|
885
|
+
try {
|
|
886
|
+
decoded = decodeURIComponent(segment);
|
|
887
|
+
} catch {
|
|
888
|
+
decoded = segment;
|
|
889
|
+
}
|
|
890
|
+
return secretSegment(decoded) ? maskValue(decoded, false) : segment;
|
|
891
|
+
}).join("/");
|
|
892
|
+
}
|
|
893
|
+
function failureOf(error) {
|
|
894
|
+
const message = describeError(error);
|
|
895
|
+
const cause = error instanceof Error ? error.cause : void 0;
|
|
896
|
+
const detail = typeof cause?.code === "string" ? cause.code : typeof cause?.message === "string" ? cause.message : "";
|
|
897
|
+
return detail && !message.includes(detail) ? `${message} (${detail})` : message;
|
|
898
|
+
}
|
|
899
|
+
function urlOf(input) {
|
|
900
|
+
try {
|
|
901
|
+
if (typeof input === "string") return new URL(input);
|
|
902
|
+
if (input instanceof URL) return input;
|
|
903
|
+
return new URL(input.url);
|
|
904
|
+
} catch {
|
|
905
|
+
return null;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
function originOf(value) {
|
|
909
|
+
try {
|
|
910
|
+
return new URL(value).origin;
|
|
911
|
+
} catch {
|
|
912
|
+
return null;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
function targets(url, target) {
|
|
916
|
+
if (target instanceof RegExp) return target.test(url.host);
|
|
917
|
+
const wanted = target.trim().toLowerCase();
|
|
918
|
+
if (wanted.startsWith(".")) return url.hostname.toLowerCase().endsWith(wanted);
|
|
919
|
+
return url.host.toLowerCase() === wanted || url.hostname.toLowerCase() === wanted;
|
|
920
|
+
}
|
|
921
|
+
function isPlainObject(value) {
|
|
922
|
+
if (value === null || typeof value !== "object") return false;
|
|
923
|
+
const prototype = Object.getPrototypeOf(value);
|
|
924
|
+
return prototype === Object.prototype || prototype === null;
|
|
925
|
+
}
|
|
926
|
+
function withRequestId(input, init, requestId) {
|
|
927
|
+
const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : void 0));
|
|
928
|
+
if (headers.has(REQUEST_ID_HEADER)) return [input, init];
|
|
929
|
+
headers.set(REQUEST_ID_HEADER, requestId);
|
|
930
|
+
if (init === void 0 || isPlainObject(init)) return [input, { ...init, headers }];
|
|
931
|
+
return [new Request(input, init), { headers }];
|
|
932
|
+
}
|
|
933
|
+
function traceFetch(config) {
|
|
934
|
+
const current = globalThis.fetch;
|
|
935
|
+
if (typeof current !== "function" || current[WRAPPED]) return () => void 0;
|
|
936
|
+
const original = current;
|
|
937
|
+
const radarOrigin = originOf(config.endpoint);
|
|
938
|
+
const traced = async (input, init) => {
|
|
939
|
+
const url = urlOf(input);
|
|
940
|
+
if (!url || url.origin === radarOrigin || url.protocol !== "http:" && url.protocol !== "https:") return original(input, init);
|
|
941
|
+
const method = (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
|
|
942
|
+
const context = currentContext();
|
|
943
|
+
const [nextInput, nextInit] = context && config.propagateTo.some((target) => targets(url, target)) ? withRequestId(input, init, context.requestId) : [input, init];
|
|
944
|
+
const attrs = { method, host: url.host, path: outboundPath(url.pathname, config.redact) };
|
|
945
|
+
const started = performance.now();
|
|
946
|
+
try {
|
|
947
|
+
const response = await original(nextInput, nextInit);
|
|
948
|
+
config.record(response.status >= 500 ? "error" : response.status >= 400 ? "warn" : "info", { ...attrs, status: response.status, durationMs: elapsedSince(started) });
|
|
949
|
+
return response;
|
|
950
|
+
} catch (error) {
|
|
951
|
+
config.record("error", { ...attrs, error: failureOf(error), durationMs: elapsedSince(started) });
|
|
952
|
+
throw error;
|
|
953
|
+
}
|
|
954
|
+
};
|
|
955
|
+
Object.defineProperty(traced, WRAPPED, { value: original });
|
|
956
|
+
globalThis.fetch = traced;
|
|
957
|
+
return () => {
|
|
958
|
+
if (globalThis.fetch === traced) globalThis.fetch = original;
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
|
|
812
962
|
// src/transport.ts
|
|
963
|
+
var import_node_util2 = require("util");
|
|
964
|
+
var import_node_zlib = require("zlib");
|
|
813
965
|
var gzipAsync = (0, import_node_util2.promisify)(import_node_zlib.gzip);
|
|
814
966
|
var MAX_BATCH_BYTES = 9e5;
|
|
815
967
|
var GZIP_THRESHOLD_BYTES = 8192;
|
|
@@ -1037,7 +1189,7 @@ function withTimeout(promise, ms) {
|
|
|
1037
1189
|
|
|
1038
1190
|
// src/version.ts
|
|
1039
1191
|
var SDK_NAME = "@oconde/radar";
|
|
1040
|
-
var SDK_VERSION = true ? "0.
|
|
1192
|
+
var SDK_VERSION = true ? "0.3.0" : "0.0.0-dev";
|
|
1041
1193
|
|
|
1042
1194
|
// src/client.ts
|
|
1043
1195
|
var MAX_CHECK_IN_DURATION_MS = 7 * 864e5;
|
|
@@ -1049,6 +1201,7 @@ var RadarClient = class {
|
|
|
1049
1201
|
initialized = false;
|
|
1050
1202
|
closed = false;
|
|
1051
1203
|
captured = /* @__PURE__ */ new WeakSet();
|
|
1204
|
+
restoreFetch = null;
|
|
1052
1205
|
get isEnabled() {
|
|
1053
1206
|
return this.transport !== null && !this.closed;
|
|
1054
1207
|
}
|
|
@@ -1076,6 +1229,14 @@ var RadarClient = class {
|
|
|
1076
1229
|
});
|
|
1077
1230
|
}
|
|
1078
1231
|
if (this.options.captureUnhandled && (this.transport || this.options.console)) installProcessHandlers(this);
|
|
1232
|
+
if (this.options.traceFetch.enabled && (this.transport || this.options.console)) {
|
|
1233
|
+
this.restoreFetch = traceFetch({
|
|
1234
|
+
endpoint: this.options.endpoint,
|
|
1235
|
+
propagateTo: this.options.traceFetch.propagateTo,
|
|
1236
|
+
redact: this.options.redact,
|
|
1237
|
+
record: (level, attrs) => this.safely(() => this.emitLog(level, "http.client", attrs))
|
|
1238
|
+
});
|
|
1239
|
+
}
|
|
1079
1240
|
} catch (error) {
|
|
1080
1241
|
this.debugWarn(`radar.init falhou: ${describeError(error)}`);
|
|
1081
1242
|
}
|
|
@@ -1212,6 +1373,8 @@ var RadarClient = class {
|
|
|
1212
1373
|
async close(timeoutMs = 2e3) {
|
|
1213
1374
|
if (this.closed) return;
|
|
1214
1375
|
await this.flush(timeoutMs);
|
|
1376
|
+
this.restoreFetch?.();
|
|
1377
|
+
this.restoreFetch = null;
|
|
1215
1378
|
this.closed = true;
|
|
1216
1379
|
this.transport?.stop();
|
|
1217
1380
|
}
|