@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.
package/dist/index.js CHANGED
@@ -253,6 +253,12 @@ function requestPath(req) {
253
253
  const end = url.indexOf("?");
254
254
  return end >= 0 ? url.slice(0, end) : url;
255
255
  }
256
+ function matchesRequest(pattern, path, route) {
257
+ const candidates = route === void 0 ? [path] : [path, route];
258
+ if (pattern instanceof RegExp) return candidates.some((value) => value.search(pattern) !== -1);
259
+ const prefix = pattern.endsWith("/") ? pattern : `${pattern}/`;
260
+ return candidates.some((value) => value === pattern || value.startsWith(prefix));
261
+ }
256
262
  function requestRoute(req, route) {
257
263
  if (route) return route;
258
264
  if (typeof req.route?.path !== "string") return void 0;
@@ -392,11 +398,24 @@ function createMiddleware(logger) {
392
398
  // src/options.ts
393
399
  var DEFAULT_ENDPOINT = "https://radar-ingest.oconde.dev";
394
400
  var LEVELS = ["debug", "info", "warn", "error"];
401
+ function patterns(value) {
402
+ if (!Array.isArray(value)) return [];
403
+ return value.flatMap((item) => {
404
+ if (item instanceof RegExp) return [item];
405
+ if (typeof item === "string" && item.trim() !== "") return [item.trim()];
406
+ return [];
407
+ });
408
+ }
395
409
  function resolveTraceFetch(value) {
396
- if (!value) return { enabled: false, propagateTo: [] };
397
- if (value === true) return { enabled: true, propagateTo: [] };
398
- const targets2 = Array.isArray(value.propagateTo) ? value.propagateTo : [];
399
- return { enabled: true, propagateTo: targets2.filter((target) => typeof target === "string" ? target.trim() !== "" : target instanceof RegExp) };
410
+ if (!value) return { enabled: false, propagateTo: [], ignore: [] };
411
+ if (value === true) return { enabled: true, propagateTo: [], ignore: [] };
412
+ return { enabled: true, propagateTo: patterns(value.propagateTo), ignore: patterns(value.ignore) };
413
+ }
414
+ function resolveLogRequests(value) {
415
+ if (value === false) return { enabled: false, include: [], exclude: [], sample: 1 };
416
+ if (value === void 0 || value === true || typeof value !== "object" || value === null) return { enabled: true, include: [], exclude: [], sample: 1 };
417
+ const sample = typeof value.sample === "number" && Number.isFinite(value.sample) && value.sample >= 0 && value.sample <= 1 ? value.sample : 1;
418
+ return { enabled: true, include: patterns(value.include), exclude: patterns(value.exclude), sample };
400
419
  }
401
420
  function resolveOptions(options = {}, env = process.env) {
402
421
  const key = options.key?.trim() || void 0;
@@ -410,7 +429,7 @@ function resolveOptions(options = {}, env = process.env) {
410
429
  minLevel: options.minLevel && LEVELS.includes(options.minLevel) ? options.minLevel : "info",
411
430
  redact: options.redact === "none" ? "none" : "mask",
412
431
  requestDetail: options.requestDetail === "route" ? "route" : "full",
413
- logRequests: options.logRequests ?? true,
432
+ logRequests: resolveLogRequests(options.logRequests),
414
433
  ignorePaths: options.ignorePaths ?? ["/healthz", "/health"],
415
434
  captureUnhandled: options.captureUnhandled ?? true,
416
435
  traceFetch: resolveTraceFetch(options.traceFetch),
@@ -564,8 +583,8 @@ function headerOf(code, index, prefix) {
564
583
  return header;
565
584
  }
566
585
  function nameIn(header) {
567
- const patterns = ANONYMOUS_FUNCTION.test(header) ? NAME_PATTERNS : [...NAME_PATTERNS, METHOD_PATTERN];
568
- for (const pattern of patterns) {
586
+ const patterns2 = ANONYMOUS_FUNCTION.test(header) ? NAME_PATTERNS : [...NAME_PATTERNS, METHOD_PATTERN];
587
+ for (const pattern of patterns2) {
569
588
  const name = pattern.exec(header)?.[1];
570
589
  if (name && !KEYWORDS.has(name)) return name.slice(0, MAX_NAME_LENGTH);
571
590
  }
@@ -885,12 +904,19 @@ function originOf(value) {
885
904
  return null;
886
905
  }
887
906
  }
888
- function targets(url, target) {
889
- if (target instanceof RegExp) return target.test(url.host);
890
- const wanted = target.trim().toLowerCase();
907
+ function hostMatches(url, host) {
908
+ const wanted = host.trim().toLowerCase();
891
909
  if (wanted.startsWith(".")) return url.hostname.toLowerCase().endsWith(wanted);
892
910
  return url.host.toLowerCase() === wanted || url.hostname.toLowerCase() === wanted;
893
911
  }
912
+ function targets(url, target) {
913
+ if (target instanceof RegExp) return url.host.search(target) !== -1;
914
+ return hostMatches(url, target);
915
+ }
916
+ function ignored(url, target) {
917
+ if (target instanceof RegExp) return `${url.host}${url.pathname}`.search(target) !== -1;
918
+ return hostMatches(url, target);
919
+ }
894
920
  function isPlainObject(value) {
895
921
  if (value === null || typeof value !== "object") return false;
896
922
  const prototype = Object.getPrototypeOf(value);
@@ -914,6 +940,7 @@ function traceFetch(config) {
914
940
  const method = (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
915
941
  const context = currentContext();
916
942
  const [nextInput, nextInit] = context && config.propagateTo.some((target) => targets(url, target)) ? withRequestId(input, init, context.requestId) : [input, init];
943
+ if (config.ignore?.some((target) => ignored(url, target))) return original(nextInput, nextInit);
917
944
  const attrs = { method, host: url.host, path: outboundPath(url.pathname, config.redact) };
918
945
  const started = performance.now();
919
946
  try {
@@ -1162,7 +1189,7 @@ function withTimeout(promise, ms) {
1162
1189
 
1163
1190
  // src/version.ts
1164
1191
  var SDK_NAME = "@oconde/radar";
1165
- var SDK_VERSION = true ? "0.3.0" : "0.0.0-dev";
1192
+ var SDK_VERSION = true ? "0.4.1" : "0.0.0-dev";
1166
1193
 
1167
1194
  // src/client.ts
1168
1195
  var MAX_CHECK_IN_DURATION_MS = 7 * 864e5;
@@ -1206,6 +1233,7 @@ var RadarClient = class {
1206
1233
  this.restoreFetch = traceFetch({
1207
1234
  endpoint: this.options.endpoint,
1208
1235
  propagateTo: this.options.traceFetch.propagateTo,
1236
+ ignore: this.options.traceFetch.ignore,
1209
1237
  redact: this.options.redact,
1210
1238
  record: (level, attrs) => this.safely(() => this.emitLog(level, "http.client", attrs))
1211
1239
  });
@@ -1316,22 +1344,28 @@ var RadarClient = class {
1316
1344
  return createMiddleware(this);
1317
1345
  }
1318
1346
  shouldLogRequest(req) {
1319
- return this.options.logRequests && !this.options.ignorePaths.includes(requestPath(req));
1347
+ return this.options.logRequests.enabled && !this.options.ignorePaths.includes(requestPath(req));
1320
1348
  }
1321
1349
  logHttpRequest(context, status) {
1322
1350
  this.safely(() => {
1323
1351
  const req = context.req;
1324
1352
  if (!req) return;
1325
- const level = status >= 500 ? "error" : status >= 400 ? "warn" : "info";
1326
1353
  const route = requestRoute(req, context.route);
1354
+ const path = requestPath(req);
1355
+ const { include, exclude, sample } = this.options.logRequests;
1356
+ if (include.length > 0 && !include.some((pattern) => matchesRequest(pattern, path, route))) return;
1357
+ if (exclude.some((pattern) => matchesRequest(pattern, path, route))) return;
1358
+ if (sample < 1 && Math.random() >= sample) return;
1359
+ const level = status >= 500 ? "error" : status >= 400 ? "warn" : "info";
1327
1360
  runWithContext(
1328
1361
  context,
1329
1362
  () => this.emitLog(level, "http.request", {
1330
1363
  method: (req.method ?? "GET").toUpperCase(),
1331
1364
  ...route ? { route } : {},
1332
- ...this.options.requestDetail === "full" ? { path: redactPath(requestPath(req), pathParams(req, requestPath(req)), this.options.redact) } : {},
1365
+ ...this.options.requestDetail === "full" ? { path: redactPath(path, pathParams(req, path), this.options.redact) } : {},
1333
1366
  status,
1334
- durationMs: elapsedSince(context.startedAt)
1367
+ durationMs: elapsedSince(context.startedAt),
1368
+ ...sample < 1 ? { sampleRate: sample } : {}
1335
1369
  })
1336
1370
  );
1337
1371
  });