@oconde/radar 0.3.0 → 0.4.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.
@@ -287,6 +287,12 @@ function requestPath(req) {
287
287
  const end = url.indexOf("?");
288
288
  return end >= 0 ? url.slice(0, end) : url;
289
289
  }
290
+ function matchesRequest(pattern, path, route) {
291
+ const candidates = route === void 0 ? [path] : [path, route];
292
+ if (pattern instanceof RegExp) return candidates.some((value) => value.search(pattern) !== -1);
293
+ const prefix = pattern.endsWith("/") ? pattern : `${pattern}/`;
294
+ return candidates.some((value) => value === pattern || value.startsWith(prefix));
295
+ }
290
296
  function requestRoute(req, route) {
291
297
  if (route) return route;
292
298
  if (typeof req.route?.path !== "string") return void 0;
@@ -426,11 +432,24 @@ function createMiddleware(logger) {
426
432
  // src/options.ts
427
433
  var DEFAULT_ENDPOINT = "https://radar-ingest.oconde.dev";
428
434
  var LEVELS = ["debug", "info", "warn", "error"];
435
+ function patterns(value) {
436
+ if (!Array.isArray(value)) return [];
437
+ return value.flatMap((item) => {
438
+ if (item instanceof RegExp) return [item];
439
+ if (typeof item === "string" && item.trim() !== "") return [item.trim()];
440
+ return [];
441
+ });
442
+ }
429
443
  function resolveTraceFetch(value) {
430
- if (!value) return { enabled: false, propagateTo: [] };
431
- if (value === true) return { enabled: true, propagateTo: [] };
432
- const targets2 = Array.isArray(value.propagateTo) ? value.propagateTo : [];
433
- return { enabled: true, propagateTo: targets2.filter((target) => typeof target === "string" ? target.trim() !== "" : target instanceof RegExp) };
444
+ if (!value) return { enabled: false, propagateTo: [], ignore: [] };
445
+ if (value === true) return { enabled: true, propagateTo: [], ignore: [] };
446
+ return { enabled: true, propagateTo: patterns(value.propagateTo), ignore: patterns(value.ignore) };
447
+ }
448
+ function resolveLogRequests(value) {
449
+ if (value === false) return { enabled: false, include: [], exclude: [], sample: 1 };
450
+ if (value === void 0 || value === true || typeof value !== "object" || value === null) return { enabled: true, include: [], exclude: [], sample: 1 };
451
+ const sample = typeof value.sample === "number" && Number.isFinite(value.sample) && value.sample >= 0 && value.sample <= 1 ? value.sample : 1;
452
+ return { enabled: true, include: patterns(value.include), exclude: patterns(value.exclude), sample };
434
453
  }
435
454
  function resolveOptions(options = {}, env = process.env) {
436
455
  const key = options.key?.trim() || void 0;
@@ -444,7 +463,7 @@ function resolveOptions(options = {}, env = process.env) {
444
463
  minLevel: options.minLevel && LEVELS.includes(options.minLevel) ? options.minLevel : "info",
445
464
  redact: options.redact === "none" ? "none" : "mask",
446
465
  requestDetail: options.requestDetail === "route" ? "route" : "full",
447
- logRequests: options.logRequests ?? true,
466
+ logRequests: resolveLogRequests(options.logRequests),
448
467
  ignorePaths: options.ignorePaths ?? ["/healthz", "/health"],
449
468
  captureUnhandled: options.captureUnhandled ?? true,
450
469
  traceFetch: resolveTraceFetch(options.traceFetch),
@@ -598,8 +617,8 @@ function headerOf(code, index, prefix) {
598
617
  return header;
599
618
  }
600
619
  function nameIn(header) {
601
- const patterns = ANONYMOUS_FUNCTION.test(header) ? NAME_PATTERNS : [...NAME_PATTERNS, METHOD_PATTERN];
602
- for (const pattern of patterns) {
620
+ const patterns2 = ANONYMOUS_FUNCTION.test(header) ? NAME_PATTERNS : [...NAME_PATTERNS, METHOD_PATTERN];
621
+ for (const pattern of patterns2) {
603
622
  const name = pattern.exec(header)?.[1];
604
623
  if (name && !KEYWORDS.has(name)) return name.slice(0, MAX_NAME_LENGTH);
605
624
  }
@@ -942,12 +961,19 @@ function originOf(value) {
942
961
  return null;
943
962
  }
944
963
  }
945
- function targets(url, target) {
946
- if (target instanceof RegExp) return target.test(url.host);
947
- const wanted = target.trim().toLowerCase();
964
+ function hostMatches(url, host) {
965
+ const wanted = host.trim().toLowerCase();
948
966
  if (wanted.startsWith(".")) return url.hostname.toLowerCase().endsWith(wanted);
949
967
  return url.host.toLowerCase() === wanted || url.hostname.toLowerCase() === wanted;
950
968
  }
969
+ function targets(url, target) {
970
+ if (target instanceof RegExp) return url.host.search(target) !== -1;
971
+ return hostMatches(url, target);
972
+ }
973
+ function ignored(url, target) {
974
+ if (target instanceof RegExp) return `${url.host}${url.pathname}`.search(target) !== -1;
975
+ return hostMatches(url, target);
976
+ }
951
977
  function isPlainObject(value) {
952
978
  if (value === null || typeof value !== "object") return false;
953
979
  const prototype = Object.getPrototypeOf(value);
@@ -971,6 +997,7 @@ function traceFetch(config) {
971
997
  const method = (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
972
998
  const context = currentContext();
973
999
  const [nextInput, nextInit] = context && config.propagateTo.some((target) => targets(url, target)) ? withRequestId(input, init, context.requestId) : [input, init];
1000
+ if (config.ignore?.some((target) => ignored(url, target))) return original(nextInput, nextInit);
974
1001
  const attrs = { method, host: url.host, path: outboundPath(url.pathname, config.redact) };
975
1002
  const started = performance.now();
976
1003
  try {
@@ -1219,7 +1246,7 @@ function withTimeout(promise, ms) {
1219
1246
 
1220
1247
  // src/version.ts
1221
1248
  var SDK_NAME = "@oconde/radar";
1222
- var SDK_VERSION = true ? "0.3.0" : "0.0.0-dev";
1249
+ var SDK_VERSION = true ? "0.4.1" : "0.0.0-dev";
1223
1250
 
1224
1251
  // src/client.ts
1225
1252
  var MAX_CHECK_IN_DURATION_MS = 7 * 864e5;
@@ -1263,6 +1290,7 @@ var RadarClient = class {
1263
1290
  this.restoreFetch = traceFetch({
1264
1291
  endpoint: this.options.endpoint,
1265
1292
  propagateTo: this.options.traceFetch.propagateTo,
1293
+ ignore: this.options.traceFetch.ignore,
1266
1294
  redact: this.options.redact,
1267
1295
  record: (level, attrs) => this.safely(() => this.emitLog(level, "http.client", attrs))
1268
1296
  });
@@ -1373,22 +1401,28 @@ var RadarClient = class {
1373
1401
  return createMiddleware(this);
1374
1402
  }
1375
1403
  shouldLogRequest(req) {
1376
- return this.options.logRequests && !this.options.ignorePaths.includes(requestPath(req));
1404
+ return this.options.logRequests.enabled && !this.options.ignorePaths.includes(requestPath(req));
1377
1405
  }
1378
1406
  logHttpRequest(context, status) {
1379
1407
  this.safely(() => {
1380
1408
  const req = context.req;
1381
1409
  if (!req) return;
1382
- const level = status >= 500 ? "error" : status >= 400 ? "warn" : "info";
1383
1410
  const route = requestRoute(req, context.route);
1411
+ const path = requestPath(req);
1412
+ const { include, exclude, sample } = this.options.logRequests;
1413
+ if (include.length > 0 && !include.some((pattern) => matchesRequest(pattern, path, route))) return;
1414
+ if (exclude.some((pattern) => matchesRequest(pattern, path, route))) return;
1415
+ if (sample < 1 && Math.random() >= sample) return;
1416
+ const level = status >= 500 ? "error" : status >= 400 ? "warn" : "info";
1384
1417
  runWithContext(
1385
1418
  context,
1386
1419
  () => this.emitLog(level, "http.request", {
1387
1420
  method: (req.method ?? "GET").toUpperCase(),
1388
1421
  ...route ? { route } : {},
1389
- ...this.options.requestDetail === "full" ? { path: redactPath(requestPath(req), pathParams(req, requestPath(req)), this.options.redact) } : {},
1422
+ ...this.options.requestDetail === "full" ? { path: redactPath(path, pathParams(req, path), this.options.redact) } : {},
1390
1423
  status,
1391
- durationMs: elapsedSince(context.startedAt)
1424
+ durationMs: elapsedSince(context.startedAt),
1425
+ ...sample < 1 ? { sampleRate: sample } : {}
1392
1426
  })
1393
1427
  );
1394
1428
  });