logixia 1.10.0 → 1.10.2

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.
Files changed (37) hide show
  1. package/README.md +58 -2
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/index.d.mts +1 -1
  4. package/dist/index.d.mts.map +1 -1
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2 -2
  8. package/dist/index.mjs +2 -2
  9. package/dist/{logitron-logger.module-NLCrDkXA.d.mts → logitron-logger.module-B8NklSC4.d.mts} +6 -3
  10. package/dist/logitron-logger.module-B8NklSC4.d.mts.map +1 -0
  11. package/dist/{logitron-logger.module-209uTmVY.d.ts → logitron-logger.module-BLT1y5Iq.d.ts} +6 -3
  12. package/dist/logitron-logger.module-BLT1y5Iq.d.ts.map +1 -0
  13. package/dist/{logitron-logger.module-BFNsUfx7.mjs → logitron-logger.module-Bt_Jei1V.mjs} +73 -21
  14. package/dist/logitron-logger.module-Bt_Jei1V.mjs.map +1 -0
  15. package/dist/{logitron-logger.module-DC0qwI3N.js → logitron-logger.module-bJ1hGhaL.js} +73 -21
  16. package/dist/logitron-logger.module-bJ1hGhaL.js.map +1 -0
  17. package/dist/nest.d.mts +1 -1
  18. package/dist/nest.d.ts +1 -1
  19. package/dist/nest.js +2 -2
  20. package/dist/nest.mjs +2 -2
  21. package/dist/{transport.manager-DsvWfJ_b.mjs → transport.manager-CaL4XuLD.mjs} +36 -17
  22. package/dist/transport.manager-CaL4XuLD.mjs.map +1 -0
  23. package/dist/{transport.manager-CgeSNG_8.js → transport.manager-zgEZCJhR.js} +36 -17
  24. package/dist/transport.manager-zgEZCJhR.js.map +1 -0
  25. package/dist/transports.d.mts +14 -1
  26. package/dist/transports.d.mts.map +1 -1
  27. package/dist/transports.d.ts +14 -1
  28. package/dist/transports.d.ts.map +1 -1
  29. package/dist/transports.js +1 -1
  30. package/dist/transports.mjs +1 -1
  31. package/package.json +1 -1
  32. package/dist/logitron-logger.module-209uTmVY.d.ts.map +0 -1
  33. package/dist/logitron-logger.module-BFNsUfx7.mjs.map +0 -1
  34. package/dist/logitron-logger.module-DC0qwI3N.js.map +0 -1
  35. package/dist/logitron-logger.module-NLCrDkXA.d.mts.map +0 -1
  36. package/dist/transport.manager-CgeSNG_8.js.map +0 -1
  37. package/dist/transport.manager-DsvWfJ_b.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- const require_transport_manager = require('./transport.manager-CgeSNG_8.js');
1
+ const require_transport_manager = require('./transport.manager-zgEZCJhR.js');
2
2
  let fast_json_stringify = require("fast-json-stringify");
3
3
  fast_json_stringify = require_transport_manager.__toESM(fast_json_stringify);
4
4
  let node_async_hooks = require("node:async_hooks");
@@ -119,8 +119,14 @@ var PluginRegistry = class {
119
119
  let current = entry;
120
120
  for (const plugin of this._plugins) {
121
121
  if (!plugin.onLog) continue;
122
- current = await plugin.onLog(current);
123
- if (current === null) return null;
122
+ let next;
123
+ try {
124
+ next = await plugin.onLog(current);
125
+ } catch {
126
+ continue;
127
+ }
128
+ if (next === null) return null;
129
+ current = next;
124
130
  }
125
131
  return current;
126
132
  }
@@ -499,7 +505,11 @@ function resolveConfig(config) {
499
505
  }
500
506
  /**
501
507
  * Convert a dot-notation path pattern to a RegExp.
502
- * Supports `*` (one segment) and `**` (zero or more segments).
508
+ * Supports `*` (exactly one segment) and `**` (zero or more segments).
509
+ *
510
+ * Because `**` may match *zero* segments, it also absorbs the dot separator
511
+ * that joins it to its neighbour — so `**.password` matches both a bare
512
+ * top-level `password` (zero leading segments) and any nested `*.password`.
503
513
  *
504
514
  * Examples:
505
515
  * "password" → /^password$/
@@ -507,13 +517,26 @@ function resolveConfig(config) {
507
517
  * "*.token" → /^[^.]+\.token$/
508
518
  * "req.headers.*" → /^req\.headers\.[^.]+$/
509
519
  * "**" → /^.*$/
520
+ * "**.password" → /^(?:.*\.)?password$/ (matches `password` and `a.b.password`)
521
+ * "req.**" → /^req(?:\..*)?$/ (matches `req` and `req.a.b`)
522
+ *
523
+ * Consecutive `**` segments are collapsed (`a.**.**.b` ≡ `a.**.b`).
510
524
  */
511
525
  function pathToRegExp(pattern) {
512
- const regexStr = pattern.split(".").map((segment) => {
513
- if (segment === "**") return ".*";
514
- if (segment === "*") return "[^.]+";
515
- return segment.replace(/[$()*+.?[\\\]^{|}]/g, "\\$&");
516
- }).join("\\.");
526
+ const segments = pattern.split(".").filter((seg, i, arr) => !(seg === "**" && arr[i - 1] === "**"));
527
+ const lastIndex = segments.length - 1;
528
+ let regexStr = "";
529
+ for (const [i, segment] of segments.entries()) {
530
+ const prevOwnsRightDot = i > 0 && segments[i - 1] === "**" && i - 1 < lastIndex;
531
+ if (i > 0 && !prevOwnsRightDot && !(segment === "**" && i === lastIndex && i > 0)) regexStr += String.raw`\.`;
532
+ if (segment === "**") {
533
+ if (lastIndex === 0) regexStr += ".*";
534
+ else if (i === lastIndex) regexStr += String.raw`(?:\..*)?`;
535
+ else regexStr += String.raw`(?:.*\.)?`;
536
+ continue;
537
+ }
538
+ regexStr += segment === "*" ? "[^.]+" : segment.replace(/[$()*+.?[\\\]^{|}]/g, "\\$&");
539
+ }
517
540
  return /* @__PURE__ */ new RegExp(`^${regexStr}$`);
518
541
  }
519
542
  /** Pre-compiled path matchers keyed by pattern string for perf */
@@ -580,7 +603,11 @@ function isPlainObject(value) {
580
603
 
581
604
  //#endregion
582
605
  //#region src/utils/sampling.utils.ts
583
- const ALWAYS_EMIT_LEVELS = new Set(["error", "fatal"]);
606
+ const ALWAYS_EMIT_LEVELS = new Set([
607
+ "error",
608
+ "warn",
609
+ "fatal"
610
+ ]);
584
611
  var Sampler = class {
585
612
  constructor(config, onStats) {
586
613
  this.sampledTraces = /* @__PURE__ */ new Set();
@@ -714,6 +741,9 @@ var Sampler = class {
714
741
  /** Module-level registry of all logger instances that have opted into graceful shutdown */
715
742
  const registry = /* @__PURE__ */ new Set();
716
743
  let shutdownHandlerRegistered = false;
744
+ /** Our own handler + the signals we attached it to, so reset() can detach exactly it. */
745
+ let activeHandler;
746
+ let activeSignals = [];
717
747
  /**
718
748
  * Register a logger instance so it is included in the graceful shutdown flush.
719
749
  * Called automatically when `gracefulShutdown: true` is set in logger config.
@@ -755,7 +785,9 @@ function flushOnExit(options = {}) {
755
785
  process.exit(0);
756
786
  }
757
787
  };
758
- for (const signal of signals) if (process.listenerCount(signal) === 0) process.on(signal, handler);
788
+ activeHandler = handler;
789
+ activeSignals = signals;
790
+ for (const signal of signals) process.on(signal, activeHandler);
759
791
  }
760
792
  /**
761
793
  * Remove all graceful shutdown handlers and clear the registry.
@@ -763,6 +795,9 @@ function flushOnExit(options = {}) {
763
795
  */
764
796
  function resetShutdownHandlers() {
765
797
  registry.clear();
798
+ if (activeHandler) for (const signal of activeSignals) process.removeListener(signal, activeHandler);
799
+ activeHandler = void 0;
800
+ activeSignals = [];
766
801
  shutdownHandlerRegistered = false;
767
802
  }
768
803
 
@@ -989,6 +1024,17 @@ function toValidTraceId(value) {
989
1024
  const trimmed = first.trim();
990
1025
  return trimmed.length > 0 ? trimmed : void 0;
991
1026
  }
1027
+ /** W3C trace-context: `version-traceId(32hex)-spanId(16hex)-flags(2hex)`. */
1028
+ const W3C_TRACEPARENT_RE = /^[\da-f]{2}-([\da-f]{32})-[\da-f]{16}-[\da-f]{2}$/i;
1029
+ /**
1030
+ * Extract the 32-hex trace-id segment from a W3C `traceparent` header value.
1031
+ * Returns the parsed trace ID, or the original value unchanged when it is not a
1032
+ * well-formed traceparent (so non-W3C propagation still works).
1033
+ */
1034
+ function parseTraceparent(value) {
1035
+ const m = W3C_TRACEPARENT_RE.exec(value);
1036
+ return m ? m[1] : value;
1037
+ }
992
1038
  /** Extract trace ID from request using configuration (header → query → body → params). */
993
1039
  function extractTraceId(request, config) {
994
1040
  const req = request;
@@ -996,8 +1042,9 @@ function extractTraceId(request, config) {
996
1042
  const headers = Array.isArray(config.header) ? config.header : [config.header];
997
1043
  for (const header of headers) {
998
1044
  var _req$headers;
999
- const value = toValidTraceId((_req$headers = req.headers) === null || _req$headers === void 0 ? void 0 : _req$headers[header.toLowerCase()]);
1000
- if (value) return value;
1045
+ const lower = header.toLowerCase();
1046
+ const value = toValidTraceId((_req$headers = req.headers) === null || _req$headers === void 0 ? void 0 : _req$headers[lower]);
1047
+ if (value) return lower === "traceparent" ? parseTraceparent(value) : value;
1001
1048
  }
1002
1049
  }
1003
1050
  if (config.query) {
@@ -1175,7 +1222,7 @@ var LogixiaLogger = class LogixiaLogger {
1175
1222
  ...this.config.levelOptions,
1176
1223
  level: resolvedLevel
1177
1224
  };
1178
- if (!this.config.fields) this.config.fields = {
1225
+ this.config.fields ??= {
1179
1226
  timestamp: "[yyyy-mm-dd HH:MM:ss.MS]",
1180
1227
  level: "[log_level]",
1181
1228
  appName: "[app_name]",
@@ -1275,8 +1322,8 @@ var LogixiaLogger = class LogixiaLogger {
1275
1322
  ]) {
1276
1323
  var _this$config$fields;
1277
1324
  if (this.fieldState.has(f)) this._fieldCache.set(f, this.fieldState.get(f));
1278
- else if (((_this$config$fields = this.config.fields) === null || _this$config$fields === void 0 ? void 0 : _this$config$fields[f]) !== void 0) this._fieldCache.set(f, this.config.fields[f] !== false);
1279
- else this._fieldCache.set(f, true);
1325
+ else if (((_this$config$fields = this.config.fields) === null || _this$config$fields === void 0 ? void 0 : _this$config$fields[f]) === void 0) this._fieldCache.set(f, true);
1326
+ else this._fieldCache.set(f, this.config.fields[f] !== false);
1280
1327
  }
1281
1328
  const colorize = ((_this$config$format = this.config.format) === null || _this$config$format === void 0 ? void 0 : _this$config$format.colorize) ?? true;
1282
1329
  this._formattedLevels = /* @__PURE__ */ new Map();
@@ -1312,9 +1359,9 @@ var LogixiaLogger = class LogixiaLogger {
1312
1359
  } else this._formattedLevels.set(lvl, `[${upper}] `);
1313
1360
  }
1314
1361
  const appNameRaw = `[${this.config.appName ?? "App"}]`;
1315
- if (this._fieldCache.get("appName") !== false) this._formattedAppName = colorize ? `${this._colorMap.get("gray")}${appNameRaw}${this._colorMap.get("reset")} ` : `${appNameRaw} `;
1316
- else this._formattedAppName = "";
1317
- this._hasRedact = !!(this.config.redact && ((((_this$config$redact$p = this.config.redact.paths) === null || _this$config$redact$p === void 0 ? void 0 : _this$config$redact$p.length) ?? 0) > 0 || (((_this$config$redact$p2 = this.config.redact.patterns) === null || _this$config$redact$p2 === void 0 ? void 0 : _this$config$redact$p2.length) ?? 0) > 0));
1362
+ if (this._fieldCache.get("appName") === false) this._formattedAppName = "";
1363
+ else this._formattedAppName = colorize ? `${this._colorMap.get("gray")}${appNameRaw}${this._colorMap.get("reset")} ` : `${appNameRaw} `;
1364
+ this._hasRedact = !!(this.config.redact && ((((_this$config$redact$p = this.config.redact.paths) === null || _this$config$redact$p === void 0 ? void 0 : _this$config$redact$p.length) ?? 0) > 0 || (((_this$config$redact$p2 = this.config.redact.patterns) === null || _this$config$redact$p2 === void 0 ? void 0 : _this$config$redact$p2.length) ?? 0) > 0 || !!this.config.redact.autoDetect));
1318
1365
  }
1319
1366
  async error(messageOrError, data) {
1320
1367
  if (isError(messageOrError)) await this.log("error", messageOrError.message, {
@@ -1456,10 +1503,14 @@ var LogixiaLogger = class LogixiaLogger {
1456
1503
  }
1457
1504
  child(context, data) {
1458
1505
  const childLogger = new LogixiaLogger(this.config, context);
1459
- if (data) childLogger.contextData = {
1506
+ const mergedContextData = {
1460
1507
  ...this.contextData,
1461
1508
  ...data
1462
1509
  };
1510
+ if (Object.keys(mergedContextData).length > 0) {
1511
+ childLogger.contextData = mergedContextData;
1512
+ childLogger._hasContextData = true;
1513
+ }
1463
1514
  return childLogger;
1464
1515
  }
1465
1516
  /**
@@ -1615,6 +1666,7 @@ var LogixiaLogger = class LogixiaLogger {
1615
1666
  return;
1616
1667
  } catch (error) {
1617
1668
  require_transport_manager.internalError("Transport write failed", error);
1669
+ if (this._pluginRegistry.size > 0) await this._pluginRegistry.runOnError(error instanceof Error ? error : new Error(String(error)), entry);
1618
1670
  }
1619
1671
  (level === LogLevel.ERROR ? process.stderr : process.stdout).write(message + "\n");
1620
1672
  }
@@ -2567,4 +2619,4 @@ Object.defineProperty(exports, 'usePlugin', {
2567
2619
  return usePlugin;
2568
2620
  }
2569
2621
  });
2570
- //# sourceMappingURL=logitron-logger.module-DC0qwI3N.js.map
2622
+ //# sourceMappingURL=logitron-logger.module-bJ1hGhaL.js.map