voltlog-io 1.0.1 → 1.0.3

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
@@ -1,71 +1,9 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
33
- LogLevel: () => LogLevel,
34
- LogLevelNameMap: () => LogLevelNameMap,
35
- LogLevelValueMap: () => LogLevelValueMap,
36
- aiEnrichmentMiddleware: () => aiEnrichmentMiddleware,
37
- alertMiddleware: () => alertMiddleware,
38
- batchTransport: () => batchTransport,
39
- browserJsonStreamTransport: () => browserJsonStreamTransport,
40
- consoleTransport: () => consoleTransport,
41
- correlationIdMiddleware: () => correlationIdMiddleware,
42
- createLogger: () => createLogger,
43
- createMiddleware: () => createMiddleware,
44
- createOpenAiErrorAnalyzer: () => createOpenAiErrorAnalyzer,
45
- createTransport: () => createTransport,
46
- datadogTransport: () => datadogTransport,
47
- deduplicationMiddleware: () => deduplicationMiddleware,
48
- discordTransport: () => discordTransport,
49
- fileTransport: () => fileTransport,
50
- heapUsageMiddleware: () => heapUsageMiddleware,
51
- ipMiddleware: () => ipMiddleware,
52
- jsonStreamTransport: () => jsonStreamTransport,
53
- levelOverrideMiddleware: () => levelOverrideMiddleware,
54
- lokiTransport: () => lokiTransport,
55
- ocppMiddleware: () => ocppMiddleware,
56
- prettyTransport: () => prettyTransport,
57
- redactionMiddleware: () => redactionMiddleware,
58
- redisTransport: () => redisTransport,
59
- resolveLevel: () => resolveLevel,
60
- samplingMiddleware: () => samplingMiddleware,
61
- sentryTransport: () => sentryTransport,
62
- shouldIncludeStack: () => shouldIncludeStack,
63
- shouldLog: () => shouldLog,
64
- slackTransport: () => slackTransport,
65
- userAgentMiddleware: () => userAgentMiddleware,
66
- webhookTransport: () => webhookTransport
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
67
6
  });
68
- module.exports = __toCommonJS(src_exports);
69
7
 
70
8
  // src/core/types.ts
71
9
  var LogLevel = {
@@ -98,7 +36,7 @@ function shouldIncludeStack(entryLevel, includeStack) {
98
36
  }
99
37
 
100
38
  // src/core/logger.ts
101
- var import_cuid2 = require("@paralleldrive/cuid2");
39
+ var _crypto = require('crypto');
102
40
 
103
41
  // src/core/pipeline.ts
104
42
  function composeMiddleware(middleware, final) {
@@ -126,43 +64,50 @@ function fanOutToTransports(entry, transports, loggerLevel) {
126
64
  result.catch(() => {
127
65
  });
128
66
  }
129
- } catch {
67
+ } catch (e2) {
130
68
  }
131
69
  }
132
70
  }
133
71
 
134
72
  // src/core/logger.ts
135
73
  var LoggerImpl = class {
136
- _level;
137
- _transports;
138
- _middlewareList;
139
- _pipeline;
140
- _context;
141
- _includeStack;
142
- _timestampFn;
74
+
75
+
76
+
77
+
78
+
79
+
80
+
81
+
143
82
  constructor(options = {}) {
144
- this._level = resolveLevel(options.level ?? "INFO");
145
- this._transports = [...options.transports ?? []];
146
- this._middlewareList = [...options.middleware ?? []];
83
+ this._level = resolveLevel(_nullishCoalesce(options.level, () => ( "INFO")));
84
+ this._transports = [..._nullishCoalesce(options.transports, () => ( []))];
85
+ this._middlewareList = [..._nullishCoalesce(options.middleware, () => ( []))];
147
86
  this._context = options.context ? { ...options.context } : {};
148
- this._includeStack = options.includeStack ?? "ERROR";
149
- this._timestampFn = options.timestamp ?? Date.now;
87
+ this._includeStack = _nullishCoalesce(options.includeStack, () => ( "ERROR"));
88
+ this._timestampFn = _nullishCoalesce(options.timestamp, () => ( Date.now));
89
+ this._idFn = options.idGenerator !== void 0 ? options.idGenerator : _crypto.randomUUID;
150
90
  this._pipeline = this._buildPipeline();
151
91
  }
152
92
  // ─── Log Methods ────────────────────────────────────────────
153
93
  trace(message, meta) {
94
+ if (10 < this._level) return;
154
95
  this._log(10, "TRACE", message, meta);
155
96
  }
156
97
  debug(message, meta) {
98
+ if (20 < this._level) return;
157
99
  this._log(20, "DEBUG", message, meta);
158
100
  }
159
101
  info(message, meta) {
102
+ if (30 < this._level) return;
160
103
  this._log(30, "INFO", message, meta);
161
104
  }
162
105
  warn(message, meta) {
106
+ if (40 < this._level) return;
163
107
  this._log(40, "WARN", message, meta);
164
108
  }
165
109
  error(message, metaOrError, error) {
110
+ if (50 < this._level) return;
166
111
  if (metaOrError instanceof Error) {
167
112
  this._log(50, "ERROR", message, void 0, metaOrError);
168
113
  } else {
@@ -191,13 +136,41 @@ var LoggerImpl = class {
191
136
  this._middlewareList.push(middleware);
192
137
  this._pipeline = this._buildPipeline();
193
138
  }
139
+ removeMiddleware(middleware) {
140
+ this._middlewareList = this._middlewareList.filter((m) => m !== middleware);
141
+ this._pipeline = this._buildPipeline();
142
+ }
143
+ // ─── Level Control ─────────────────────────────────────────
144
+ setLevel(level) {
145
+ this._level = resolveLevel(level);
146
+ }
147
+ getLevel() {
148
+ return _nullishCoalesce(LogLevelValueMap[this._level], () => ( "INFO"));
149
+ }
150
+ isLevelEnabled(level) {
151
+ return resolveLevel(level) >= this._level;
152
+ }
153
+ // ─── Timer ─────────────────────────────────────────────────
154
+ startTimer(level) {
155
+ const start = performance.now();
156
+ const logLevel = _nullishCoalesce(level, () => ( "INFO"));
157
+ return {
158
+ done: (message, meta) => {
159
+ const durationMs = Math.round(performance.now() - start);
160
+ const merged = { ...meta, durationMs };
161
+ const methodKey = logLevel.toLowerCase();
162
+ this[methodKey](message, merged);
163
+ },
164
+ elapsed: () => Math.round(performance.now() - start)
165
+ };
166
+ }
194
167
  // ─── Lifecycle ──────────────────────────────────────────────
195
168
  async flush() {
196
- await Promise.all(this._transports.map((t) => t.flush?.()).filter(Boolean));
169
+ await Promise.all(this._transports.map((t) => _optionalChain([t, 'access', _2 => _2.flush, 'optionalCall', _3 => _3()])).filter(Boolean));
197
170
  }
198
171
  async close() {
199
172
  await this.flush();
200
- await Promise.all(this._transports.map((t) => t.close?.()).filter(Boolean));
173
+ await Promise.all(this._transports.map((t) => _optionalChain([t, 'access', _4 => _4.close, 'optionalCall', _5 => _5()])).filter(Boolean));
201
174
  }
202
175
  // ─── Internal ───────────────────────────────────────────────
203
176
  /** @internal */
@@ -208,24 +181,19 @@ var LoggerImpl = class {
208
181
  _logWithContext(level, levelName, message, context, meta, error) {
209
182
  if (!shouldLog(level, this._level)) return;
210
183
  const entry = {
211
- id: (0, import_cuid2.createId)(),
184
+ id: this._idFn ? this._idFn() : "",
212
185
  level,
213
186
  levelName,
214
187
  message,
215
188
  timestamp: this._timestampFn(),
216
- meta: meta ?? {},
189
+ meta: _nullishCoalesce(meta, () => ( {})),
217
190
  context: Object.keys(context).length > 0 ? context : void 0
218
191
  };
219
192
  if (error) {
220
- const logError = {
221
- message: error.message,
222
- name: error.name,
223
- code: error.code
224
- };
225
- if (shouldIncludeStack(level, this._includeStack)) {
226
- logError.stack = error.stack;
227
- }
228
- entry.error = logError;
193
+ entry.error = serializeError(
194
+ error,
195
+ shouldIncludeStack(level, this._includeStack)
196
+ );
229
197
  }
230
198
  this._pipeline(entry);
231
199
  }
@@ -235,6 +203,20 @@ var LoggerImpl = class {
235
203
  });
236
204
  }
237
205
  };
206
+ function serializeError(error, includeStack, depth = 0) {
207
+ const logError = {
208
+ message: error.message,
209
+ name: error.name,
210
+ code: error.code
211
+ };
212
+ if (includeStack) {
213
+ logError.stack = error.stack;
214
+ }
215
+ if (error.cause instanceof Error && depth < 5) {
216
+ logError.cause = serializeError(error.cause, includeStack, depth + 1);
217
+ }
218
+ return logError;
219
+ }
238
220
  var ChildLoggerImpl = class _ChildLoggerImpl {
239
221
  constructor(_parent, _context) {
240
222
  this._parent = _parent;
@@ -309,6 +291,21 @@ var ChildLoggerImpl = class _ChildLoggerImpl {
309
291
  addMiddleware(middleware) {
310
292
  this._parent.addMiddleware(middleware);
311
293
  }
294
+ removeMiddleware(middleware) {
295
+ this._parent.removeMiddleware(middleware);
296
+ }
297
+ setLevel(level) {
298
+ this._parent.setLevel(level);
299
+ }
300
+ getLevel() {
301
+ return this._parent.getLevel();
302
+ }
303
+ isLevelEnabled(level) {
304
+ return this._parent.isLevelEnabled(level);
305
+ }
306
+ startTimer(level) {
307
+ return this._parent.startTimer(level);
308
+ }
312
309
  flush() {
313
310
  return this._parent.flush();
314
311
  }
@@ -322,10 +319,10 @@ function createLogger(options) {
322
319
 
323
320
  // src/middleware/ai-enrichment.ts
324
321
  function aiEnrichmentMiddleware(options) {
325
- const minLevel = resolveLevel(options.level ?? "ERROR");
326
- const timeoutMs = options.timeout ?? 2e3;
327
- const swallow = options.swallowErrors ?? true;
328
- const fieldName = options.targetField ?? "ai_analysis";
322
+ const minLevel = resolveLevel(_nullishCoalesce(options.level, () => ( "ERROR")));
323
+ const timeoutMs = _nullishCoalesce(options.timeout, () => ( 2e3));
324
+ const swallow = _nullishCoalesce(options.swallowErrors, () => ( true));
325
+ const fieldName = _nullishCoalesce(options.targetField, () => ( "ai_analysis"));
329
326
  return async (entry, next) => {
330
327
  if (entry.level < minLevel) {
331
328
  next(entry);
@@ -378,8 +375,8 @@ Context: ${JSON.stringify(entry.meta)}`
378
375
  );
379
376
  if (!response.ok) return null;
380
377
  const data = await response.json();
381
- return data.choices?.[0]?.message?.content ?? null;
382
- } catch {
378
+ return _nullishCoalesce(_optionalChain([data, 'access', _6 => _6.choices, 'optionalAccess', _7 => _7[0], 'optionalAccess', _8 => _8.message, 'optionalAccess', _9 => _9.content]), () => ( null));
379
+ } catch (e3) {
383
380
  return null;
384
381
  }
385
382
  };
@@ -396,9 +393,9 @@ function alertMiddleware(rules) {
396
393
  for (const rule of rules) {
397
394
  if (!rule.when(entry)) continue;
398
395
  const state = states.get(rule.name);
399
- const windowMs = rule.windowMs ?? Infinity;
400
- const threshold = rule.threshold ?? 1;
401
- const cooldownMs = rule.cooldownMs ?? 0;
396
+ const windowMs = _nullishCoalesce(rule.windowMs, () => ( Infinity));
397
+ const threshold = _nullishCoalesce(rule.threshold, () => ( 1));
398
+ const cooldownMs = _nullishCoalesce(rule.cooldownMs, () => ( 0));
402
399
  if (Number.isFinite(windowMs)) {
403
400
  state.entries = state.entries.filter(
404
401
  (e) => now - e.timestamp < windowMs
@@ -415,7 +412,7 @@ function alertMiddleware(rules) {
415
412
  result.catch(() => {
416
413
  });
417
414
  }
418
- } catch {
415
+ } catch (e4) {
419
416
  }
420
417
  }
421
418
  }
@@ -423,11 +420,49 @@ function alertMiddleware(rules) {
423
420
  };
424
421
  }
425
422
 
423
+ // src/middleware/async-context.ts
424
+ var _async_hooks = require('async_hooks');
425
+ function asyncContextMiddleware() {
426
+ const storage = new (0, _async_hooks.AsyncLocalStorage)();
427
+ const middleware = (entry, next) => {
428
+ const ctx = storage.getStore();
429
+ if (ctx) {
430
+ const meta = entry.meta;
431
+ for (const [key, value] of Object.entries(ctx)) {
432
+ if (!(key in meta)) {
433
+ meta[key] = value;
434
+ }
435
+ }
436
+ if (ctx.requestId && !entry.correlationId) {
437
+ entry.correlationId = String(ctx.requestId);
438
+ }
439
+ }
440
+ next(entry);
441
+ };
442
+ return {
443
+ middleware,
444
+ runInContext(context, fn) {
445
+ const parentCtx = storage.getStore();
446
+ const mergedCtx = parentCtx ? { ...parentCtx, ...context } : { ...context };
447
+ storage.run(mergedCtx, fn);
448
+ },
449
+ getContext() {
450
+ return storage.getStore();
451
+ },
452
+ updateContext(updates) {
453
+ const ctx = storage.getStore();
454
+ if (ctx) {
455
+ Object.assign(ctx, updates);
456
+ }
457
+ }
458
+ };
459
+ }
460
+
426
461
  // src/middleware/correlation-id.ts
427
- var import_cuid22 = require("@paralleldrive/cuid2");
462
+
428
463
  function correlationIdMiddleware(options = {}) {
429
- const header = options.header ?? "x-correlation-id";
430
- const generate = options.generator ?? import_cuid22.createId;
464
+ const header = _nullishCoalesce(options.header, () => ( "x-correlation-id"));
465
+ const generate = _nullishCoalesce(options.generator, () => ( _crypto.randomUUID));
431
466
  return (entry, next) => {
432
467
  if (entry.correlationId) {
433
468
  return next(entry);
@@ -452,8 +487,8 @@ function createMiddleware(fn) {
452
487
 
453
488
  // src/middleware/deduplication.ts
454
489
  function deduplicationMiddleware(options = {}) {
455
- const windowMs = options.windowMs ?? 1e3;
456
- const keyFn = options.keyFn ?? ((e) => `${e.level}:${e.message}:${e.error?.message ?? ""}`);
490
+ const windowMs = _nullishCoalesce(options.windowMs, () => ( 1e3));
491
+ const keyFn = _nullishCoalesce(options.keyFn, () => ( ((e) => `${e.level}:${e.message}:${_nullishCoalesce(_optionalChain([e, 'access', _10 => _10.error, 'optionalAccess', _11 => _11.message]), () => ( ""))}`)));
457
492
  const buffer = /* @__PURE__ */ new Map();
458
493
  return (entry, next) => {
459
494
  const key = keyFn(entry);
@@ -485,7 +520,7 @@ function deduplicationMiddleware(options = {}) {
485
520
 
486
521
  // src/middleware/heap-usage.ts
487
522
  function heapUsageMiddleware(options = {}) {
488
- const fieldName = options.fieldName ?? "memory";
523
+ const fieldName = _nullishCoalesce(options.fieldName, () => ( "memory"));
489
524
  return (entry, next) => {
490
525
  if (typeof process !== "undefined" && process.memoryUsage) {
491
526
  const memory = process.memoryUsage();
@@ -502,16 +537,81 @@ function heapUsageMiddleware(options = {}) {
502
537
  };
503
538
  }
504
539
 
540
+ // src/middleware/http.ts
541
+ var nodeHttpMappers = {
542
+ req: {
543
+ getMethod: (req) => req.method || "UNKNOWN",
544
+ getUrl: (req) => req.originalUrl || req.url || "/",
545
+ getIp: (req) => req.ip || _optionalChain([req, 'access', _12 => _12.socket, 'optionalAccess', _13 => _13.remoteAddress]) || _optionalChain([req, 'access', _14 => _14.headers, 'optionalAccess', _15 => _15["x-forwarded-for"]]) || void 0,
546
+ getUserAgent: (req) => _optionalChain([req, 'access', _16 => _16.headers, 'optionalAccess', _17 => _17["user-agent"]]) || void 0,
547
+ getHeader: (req, name) => _optionalChain([req, 'access', _18 => _18.headers, 'optionalAccess', _19 => _19[name]]) || void 0
548
+ },
549
+ res: {
550
+ getStatusCode: (res) => res.statusCode || 200,
551
+ onFinish: (res, callback) => {
552
+ if (typeof res.on === "function") {
553
+ res.on("finish", callback);
554
+ res.on("close", callback);
555
+ } else {
556
+ callback();
557
+ }
558
+ }
559
+ }
560
+ };
561
+ function createHttpLogger(logger, options) {
562
+ const {
563
+ reqMapper,
564
+ resMapper,
565
+ level = "INFO",
566
+ skip,
567
+ extractContext
568
+ } = options;
569
+ return (req, res) => {
570
+ if (_optionalChain([skip, 'optionalCall', _20 => _20(req)])) {
571
+ return;
572
+ }
573
+ const startTime = performance.now();
574
+ let finished = false;
575
+ resMapper.onFinish(res, () => {
576
+ if (finished) return;
577
+ finished = true;
578
+ const durationMs = Math.round(performance.now() - startTime);
579
+ const statusCode = resMapper.getStatusCode(res);
580
+ const method = reqMapper.getMethod(req);
581
+ const url = reqMapper.getUrl(req);
582
+ const meta = {
583
+ method,
584
+ url,
585
+ statusCode,
586
+ durationMs,
587
+ ip: reqMapper.getIp ? reqMapper.getIp(req) : void 0,
588
+ userAgent: reqMapper.getUserAgent ? reqMapper.getUserAgent(req) : void 0
589
+ };
590
+ if (extractContext) {
591
+ Object.assign(meta, extractContext(req, res));
592
+ }
593
+ let finalLevel = level;
594
+ if (statusCode >= 500) finalLevel = "ERROR";
595
+ else if (statusCode >= 400 && level === "INFO") finalLevel = "WARN";
596
+ const methodKey = finalLevel.toLowerCase();
597
+ logger[methodKey](
598
+ `${method} ${url} - ${statusCode} (${durationMs}ms)`,
599
+ meta
600
+ );
601
+ });
602
+ };
603
+ }
604
+
505
605
  // src/middleware/ip.ts
506
606
  function ipMiddleware(options = {}) {
507
- const targetField = options.fieldName ?? "ip";
508
- const keysToCheck = options.headerKeys ?? [
607
+ const targetField = _nullishCoalesce(options.fieldName, () => ( "ip"));
608
+ const keysToCheck = _nullishCoalesce(options.headerKeys, () => ( [
509
609
  "x-forwarded-for",
510
610
  "x-real-ip",
511
611
  "req.ip",
512
612
  "ip",
513
613
  "x-client-ip"
514
- ];
614
+ ]));
515
615
  return (entry, next) => {
516
616
  const meta = entry.meta;
517
617
  const headers = meta.headers || {};
@@ -548,12 +648,12 @@ function ipMiddleware(options = {}) {
548
648
 
549
649
  // src/middleware/level-override.ts
550
650
  function levelOverrideMiddleware(options = {}) {
551
- const key = options.key ?? "x-log-level";
552
- const cleanup = options.cleanup ?? true;
651
+ const key = _nullishCoalesce(options.key, () => ( "x-log-level"));
652
+ const cleanup = _nullishCoalesce(options.cleanup, () => ( true));
553
653
  return (entry, next) => {
554
654
  const meta = entry.meta;
555
655
  const context = entry.context;
556
- const levelName = meta[key] || context?.[key] || meta.headers?.[key];
656
+ const levelName = meta[key] || _optionalChain([context, 'optionalAccess', _21 => _21[key]]) || _optionalChain([meta, 'access', _22 => _22.headers, 'optionalAccess', _23 => _23[key]]);
557
657
  if (levelName && typeof levelName === "string") {
558
658
  const upperName = levelName.toUpperCase();
559
659
  if (LogLevel[upperName]) {
@@ -573,14 +673,14 @@ function levelOverrideMiddleware(options = {}) {
573
673
 
574
674
  // src/middleware/ocpp.ts
575
675
  function ocppMiddleware(options = {}) {
576
- const autoPayloadSize = options.autoPayloadSize ?? true;
577
- const propagateCorrelationId = options.propagateCorrelationId ?? true;
676
+ const autoPayloadSize = _nullishCoalesce(options.autoPayloadSize, () => ( true));
677
+ const propagateCorrelationId = _nullishCoalesce(options.propagateCorrelationId, () => ( true));
578
678
  return (entry, next) => {
579
679
  const enriched = { ...entry, meta: { ...entry.meta } };
580
680
  if (autoPayloadSize && enriched.meta.payloadSize === void 0 && enriched.meta.action) {
581
681
  try {
582
682
  enriched.meta.payloadSize = JSON.stringify(enriched.meta).length;
583
- } catch {
683
+ } catch (e5) {
584
684
  }
585
685
  }
586
686
  if (propagateCorrelationId && enriched.meta.correlationId && !enriched.correlationId) {
@@ -590,12 +690,49 @@ function ocppMiddleware(options = {}) {
590
690
  };
591
691
  }
592
692
 
693
+ // src/middleware/otel-trace.ts
694
+ function otelTraceMiddleware(options = {}) {
695
+ let traceApi = _nullishCoalesce(options.traceApi, () => ( null));
696
+ let resolved = !!traceApi;
697
+ if (!resolved) {
698
+ try {
699
+ const { createRequire } = __require("module");
700
+ const dynamicRequire = createRequire(__filename);
701
+ const api = dynamicRequire("@opentelemetry/api");
702
+ traceApi = api;
703
+ resolved = true;
704
+ } catch (e6) {
705
+ }
706
+ }
707
+ return (entry, next) => {
708
+ if (resolved && _optionalChain([traceApi, 'optionalAccess', _24 => _24.trace])) {
709
+ try {
710
+ const activeSpan = _optionalChain([traceApi, 'access', _25 => _25.trace, 'access', _26 => _26.getActiveSpan, 'optionalCall', _27 => _27()]);
711
+ if (activeSpan) {
712
+ const spanContext = _optionalChain([activeSpan, 'access', _28 => _28.spanContext, 'optionalCall', _29 => _29()]);
713
+ if (spanContext) {
714
+ const meta = entry.meta;
715
+ meta.traceId = spanContext.traceId;
716
+ meta.spanId = spanContext.spanId;
717
+ meta.traceFlags = spanContext.traceFlags;
718
+ if (!entry.correlationId) {
719
+ entry.correlationId = spanContext.traceId;
720
+ }
721
+ }
722
+ }
723
+ } catch (e7) {
724
+ }
725
+ }
726
+ next(entry);
727
+ };
728
+ }
729
+
593
730
  // src/middleware/redaction.ts
594
731
  var DEFAULT_REDACT_VALUE = "[REDACTED]";
595
732
  function redactionMiddleware(options) {
596
733
  const paths = new Set(options.paths.map((p) => p.toLowerCase()));
597
- const replacement = options.replacement ?? DEFAULT_REDACT_VALUE;
598
- const deep = options.deep ?? true;
734
+ const replacement = _nullishCoalesce(options.replacement, () => ( DEFAULT_REDACT_VALUE));
735
+ const deep = _nullishCoalesce(options.deep, () => ( true));
599
736
  function redactObject(obj) {
600
737
  const result = {};
601
738
  for (const [key, value] of Object.entries(obj)) {
@@ -625,11 +762,11 @@ function redactionMiddleware(options) {
625
762
 
626
763
  // src/middleware/sampling.ts
627
764
  function samplingMiddleware(options = {}) {
628
- const keyFn = options.keyFn ?? ((entry) => entry.message);
629
- const maxPerWindow = options.maxPerWindow ?? 100;
630
- const windowMs = options.windowMs ?? 6e4;
631
- const sampleRate = options.sampleRate ?? 1;
632
- const priorityLevel = options.priorityLevel ?? 40;
765
+ const keyFn = _nullishCoalesce(options.keyFn, () => ( ((entry) => entry.message)));
766
+ const maxPerWindow = _nullishCoalesce(options.maxPerWindow, () => ( 100));
767
+ const windowMs = _nullishCoalesce(options.windowMs, () => ( 6e4));
768
+ const sampleRate = _nullishCoalesce(options.sampleRate, () => ( 1));
769
+ const priorityLevel = _nullishCoalesce(options.priorityLevel, () => ( 40));
633
770
  const buckets = /* @__PURE__ */ new Map();
634
771
  return (entry, next) => {
635
772
  if (entry.level >= priorityLevel) {
@@ -663,11 +800,11 @@ function samplingMiddleware(options = {}) {
663
800
  // src/middleware/user-agent.ts
664
801
  function userAgentMiddleware(options = {}) {
665
802
  const sourceField = options.sourceField;
666
- const targetField = options.targetField ?? "client";
803
+ const targetField = _nullishCoalesce(options.targetField, () => ( "client"));
667
804
  return (entry, next) => {
668
805
  const meta = entry.meta;
669
806
  const context = entry.context;
670
- const ua = (sourceField ? meta[sourceField] : void 0) || meta.userAgent || meta["user-agent"] || context?.userAgent || context?.["user-agent"];
807
+ const ua = (sourceField ? meta[sourceField] : void 0) || meta.userAgent || meta["user-agent"] || _optionalChain([context, 'optionalAccess', _30 => _30.userAgent]) || _optionalChain([context, 'optionalAccess', _31 => _31["user-agent"]]);
671
808
  if (ua) {
672
809
  const info = parseUserAgent(ua);
673
810
  entry.meta = {
@@ -700,8 +837,8 @@ function parseUserAgent(ua) {
700
837
 
701
838
  // src/transports/batch.ts
702
839
  function batchTransport(inner, options = {}) {
703
- const batchSize = options.batchSize ?? 100;
704
- const flushIntervalMs = options.flushIntervalMs ?? 5e3;
840
+ const batchSize = _nullishCoalesce(options.batchSize, () => ( 100));
841
+ const flushIntervalMs = _nullishCoalesce(options.flushIntervalMs, () => ( 5e3));
705
842
  let buffer = [];
706
843
  let flushTimer = null;
707
844
  function scheduleFlush() {
@@ -722,7 +859,7 @@ function batchTransport(inner, options = {}) {
722
859
  result.catch(() => {
723
860
  });
724
861
  }
725
- } catch {
862
+ } catch (e8) {
726
863
  }
727
864
  }
728
865
  }
@@ -743,11 +880,11 @@ function batchTransport(inner, options = {}) {
743
880
  flushTimer = null;
744
881
  }
745
882
  doFlush();
746
- await inner.flush?.();
883
+ await _optionalChain([inner, 'access', _32 => _32.flush, 'optionalCall', _33 => _33()]);
747
884
  },
748
885
  async close() {
749
- await this.flush?.();
750
- await inner.close?.();
886
+ await _optionalChain([this, 'access', _34 => _34.flush, 'optionalCall', _35 => _35()]);
887
+ await _optionalChain([inner, 'access', _36 => _36.close, 'optionalCall', _37 => _37()]);
751
888
  }
752
889
  };
753
890
  }
@@ -756,8 +893,8 @@ function batchTransport(inner, options = {}) {
756
893
  function browserJsonStreamTransport(options) {
757
894
  const stream = options.stream;
758
895
  const writer = stream.getWriter();
759
- const serialize = options.serializer ?? ((entry) => `${JSON.stringify(entry)}
760
- `);
896
+ const serialize = _nullishCoalesce(options.serializer, () => ( ((entry) => `${JSON.stringify(entry)}
897
+ `)));
761
898
  return {
762
899
  name: "browser-stream",
763
900
  level: options.level,
@@ -781,8 +918,8 @@ function browserJsonStreamTransport(options) {
781
918
 
782
919
  // src/transports/console.ts
783
920
  function consoleTransport(options = {}) {
784
- const useConsoleLevels = options.useConsoleLevels ?? true;
785
- const formatter = options.formatter ?? ((entry) => JSON.stringify(entry));
921
+ const useConsoleLevels = _nullishCoalesce(options.useConsoleLevels, () => ( true));
922
+ const formatter = _nullishCoalesce(options.formatter, () => ( ((entry) => JSON.stringify(entry))));
786
923
  return {
787
924
  name: "console",
788
925
  level: options.level,
@@ -902,7 +1039,7 @@ ${JSON.stringify(entry.meta, null, 2).slice(
902
1039
  )}
903
1040
  \`\`\``
904
1041
  },
905
- entry.error?.stack ? {
1042
+ _optionalChain([entry, 'access', _38 => _38.error, 'optionalAccess', _39 => _39.stack]) ? {
906
1043
  name: "Stack",
907
1044
  value: `\`\`\`js
908
1045
  ${entry.error.stack.slice(0, 1e3)}
@@ -921,35 +1058,61 @@ function getLevelColor(level) {
921
1058
  }
922
1059
 
923
1060
  // src/transports/file.ts
924
- var import_node_fs = __toESM(require("fs"));
925
- var import_node_path = __toESM(require("path"));
1061
+ var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
1062
+ var _path = require('path'); var _path2 = _interopRequireDefault(_path);
926
1063
  function fileTransport(options) {
927
- const { dir, level } = options;
928
- const filenamePattern = options.filename ?? "app-%DATE%.log";
1064
+ const { dir, level, maxSize } = options;
1065
+ const filenamePattern = _nullishCoalesce(options.filename, () => ( "app-%DATE%.log"));
929
1066
  let currentStream = null;
930
1067
  let currentPath = "";
1068
+ let currentSize = 0;
1069
+ let rotationIndex = 0;
1070
+ let cachedDate = "";
1071
+ let cacheExpiry = 0;
1072
+ function getCachedDate() {
1073
+ const now = Date.now();
1074
+ if (now >= cacheExpiry) {
1075
+ cachedDate = new Date(now).toISOString().split("T")[0];
1076
+ cacheExpiry = now + 1e3;
1077
+ }
1078
+ return cachedDate;
1079
+ }
931
1080
  try {
932
- import_node_fs.default.mkdirSync(dir, { recursive: true });
1081
+ _fs2.default.mkdirSync(dir, { recursive: true });
933
1082
  } catch (err) {
934
1083
  console.error(`[voltlog] Failed to create log directory: ${dir}`, err);
935
1084
  }
936
- function getPath() {
937
- const now = /* @__PURE__ */ new Date();
938
- const dateStr = now.toISOString().split("T")[0];
1085
+ function getPath(sizeRotation = false) {
1086
+ const dateStr = getCachedDate();
939
1087
  const filename = filenamePattern.replace("%DATE%", dateStr);
940
- return import_node_path.default.join(dir, filename);
1088
+ if (sizeRotation && rotationIndex > 0) {
1089
+ const ext = _path2.default.extname(filename);
1090
+ const base = filename.slice(0, -ext.length || void 0);
1091
+ return _path2.default.join(dir, `${base}.${rotationIndex}${ext}`);
1092
+ }
1093
+ return _path2.default.join(dir, filename);
1094
+ }
1095
+ function openStream(filePath) {
1096
+ if (currentStream) {
1097
+ currentStream.end();
1098
+ }
1099
+ currentPath = filePath;
1100
+ currentSize = 0;
1101
+ currentStream = _fs2.default.createWriteStream(filePath, { flags: "a" });
1102
+ try {
1103
+ const stat = _fs2.default.statSync(filePath);
1104
+ currentSize = stat.size;
1105
+ } catch (e9) {
1106
+ }
1107
+ currentStream.on("error", (err) => {
1108
+ console.error(`[voltlog] File write error to ${filePath}:`, err);
1109
+ });
941
1110
  }
942
1111
  function rotate() {
943
1112
  const newPath = getPath();
944
1113
  if (newPath !== currentPath) {
945
- if (currentStream) {
946
- currentStream.end();
947
- }
948
- currentPath = newPath;
949
- currentStream = import_node_fs.default.createWriteStream(newPath, { flags: "a" });
950
- currentStream.on("error", (err) => {
951
- console.error(`[voltlog] File write error to ${newPath}:`, err);
952
- });
1114
+ rotationIndex = 0;
1115
+ openStream(newPath);
953
1116
  }
954
1117
  }
955
1118
  rotate();
@@ -958,10 +1121,15 @@ function fileTransport(options) {
958
1121
  level,
959
1122
  write(entry) {
960
1123
  rotate();
961
- if (currentStream && !currentStream.writableEnded) {
962
- const line = `${JSON.stringify(entry)}
1124
+ const line = `${JSON.stringify(entry)}
963
1125
  `;
1126
+ if (maxSize && currentSize + line.length > maxSize) {
1127
+ rotationIndex++;
1128
+ openStream(getPath(true));
1129
+ }
1130
+ if (currentStream && !currentStream.writableEnded) {
964
1131
  currentStream.write(line);
1132
+ currentSize += line.length;
965
1133
  }
966
1134
  },
967
1135
  async flush() {
@@ -969,7 +1137,7 @@ function fileTransport(options) {
969
1137
  async close() {
970
1138
  if (currentStream) {
971
1139
  return new Promise((resolve) => {
972
- currentStream?.end(() => resolve());
1140
+ _optionalChain([currentStream, 'optionalAccess', _40 => _40.end, 'call', _41 => _41(() => resolve())]);
973
1141
  });
974
1142
  }
975
1143
  }
@@ -979,8 +1147,8 @@ function fileTransport(options) {
979
1147
  // src/transports/json-stream.ts
980
1148
  function jsonStreamTransport(options) {
981
1149
  const stream = options.stream;
982
- const serialize = options.serializer ?? ((entry) => `${JSON.stringify(entry)}
983
- `);
1150
+ const serialize = _nullishCoalesce(options.serializer, () => ( ((entry) => `${JSON.stringify(entry)}
1151
+ `)));
984
1152
  return {
985
1153
  name: "json-stream",
986
1154
  level: options.level,
@@ -1002,9 +1170,13 @@ function jsonStreamTransport(options) {
1002
1170
 
1003
1171
  // src/transports/loki.ts
1004
1172
  function lokiTransport(options) {
1005
- const { host, labels = { app: "voltlog" }, level } = options;
1006
- const batchSize = options.batchSize ?? 10;
1007
- const interval = options.interval ?? 5e3;
1173
+ const { host, level } = options;
1174
+ const staticLabels = _nullishCoalesce(options.labels, () => ( { app: "voltlog" }));
1175
+ const batchSize = _nullishCoalesce(options.batchSize, () => ( 10));
1176
+ const interval = _nullishCoalesce(options.interval, () => ( 5e3));
1177
+ const includeMetadata = options.includeMetadata !== false;
1178
+ const retryEnabled = _nullishCoalesce(options.retry, () => ( false));
1179
+ const maxRetries = _nullishCoalesce(options.maxRetries, () => ( 3));
1008
1180
  const url = `${host.replace(/\/$/, "")}/loki/api/v1/push`;
1009
1181
  const headers = {
1010
1182
  "Content-Type": "application/json"
@@ -1018,44 +1190,256 @@ function lokiTransport(options) {
1018
1190
  }
1019
1191
  let buffer = [];
1020
1192
  let timer = null;
1021
- const flush = async () => {
1193
+ function buildLogLine(entry) {
1194
+ const payload = {
1195
+ level: entry.levelName,
1196
+ message: entry.message,
1197
+ ...entry.meta
1198
+ };
1199
+ if (includeMetadata) {
1200
+ if (entry.correlationId) {
1201
+ payload.correlationId = entry.correlationId;
1202
+ }
1203
+ if (entry.context) {
1204
+ payload.context = entry.context;
1205
+ }
1206
+ if (entry.error) {
1207
+ payload.error = entry.error;
1208
+ }
1209
+ }
1210
+ return JSON.stringify(payload);
1211
+ }
1212
+ function buildStreams(batch) {
1213
+ if (!options.dynamicLabels) {
1214
+ return [
1215
+ {
1216
+ stream: staticLabels,
1217
+ values: batch.map((e) => [
1218
+ String(e.timestamp * 1e6),
1219
+ // Loki wants nanoseconds
1220
+ buildLogLine(e)
1221
+ ])
1222
+ }
1223
+ ];
1224
+ }
1225
+ const grouped = /* @__PURE__ */ new Map();
1226
+ for (const entry of batch) {
1227
+ const dynamic = options.dynamicLabels(entry);
1228
+ const merged = { ...staticLabels };
1229
+ for (const [k, v] of Object.entries(dynamic)) {
1230
+ if (v !== void 0) merged[k] = v;
1231
+ }
1232
+ const key = JSON.stringify(merged);
1233
+ let group = grouped.get(key);
1234
+ if (!group) {
1235
+ group = { labels: merged, values: [] };
1236
+ grouped.set(key, group);
1237
+ }
1238
+ group.values.push([
1239
+ String(entry.timestamp * 1e6),
1240
+ buildLogLine(entry)
1241
+ ]);
1242
+ }
1243
+ return Array.from(grouped.values()).map((g) => ({
1244
+ stream: g.labels,
1245
+ values: g.values
1246
+ }));
1247
+ }
1248
+ async function pushWithRetry(batch) {
1249
+ const body = JSON.stringify({ streams: buildStreams(batch) });
1250
+ let lastError;
1251
+ const attempts = retryEnabled ? maxRetries : 1;
1252
+ for (let attempt = 0; attempt < attempts; attempt++) {
1253
+ try {
1254
+ const response = await fetch(url, { method: "POST", headers, body });
1255
+ if (response.ok) return;
1256
+ if (response.status >= 400 && response.status < 500) {
1257
+ console.error(`[voltlog] Loki push failed: ${response.status}`);
1258
+ return;
1259
+ }
1260
+ lastError = new Error(`Loki HTTP ${response.status}`);
1261
+ } catch (err) {
1262
+ lastError = err;
1263
+ }
1264
+ if (attempt < attempts - 1) {
1265
+ await new Promise((r) => setTimeout(r, 100 * 2 ** attempt));
1266
+ }
1267
+ }
1268
+ console.error("[voltlog] Loki push failed after retries", lastError);
1269
+ }
1270
+ const doFlush = async () => {
1022
1271
  if (buffer.length === 0) return;
1023
1272
  const batch = buffer;
1024
1273
  buffer = [];
1025
- const streams = [
1026
- {
1027
- stream: labels,
1028
- values: batch.map((e) => [
1029
- String(e.timestamp * 1e6),
1030
- // Loki wants nanoseconds
1031
- JSON.stringify({
1032
- level: e.levelName,
1033
- message: e.message,
1034
- ...e.meta
1035
- })
1036
- ])
1274
+ await pushWithRetry(batch);
1275
+ };
1276
+ const schedule = () => {
1277
+ if (!timer) {
1278
+ timer = setTimeout(() => {
1279
+ timer = null;
1280
+ doFlush();
1281
+ }, interval);
1282
+ }
1283
+ };
1284
+ return {
1285
+ name: "loki",
1286
+ level,
1287
+ write(entry) {
1288
+ buffer.push(entry);
1289
+ if (buffer.length >= batchSize) {
1290
+ if (timer) clearTimeout(timer);
1291
+ timer = null;
1292
+ doFlush();
1293
+ } else {
1294
+ schedule();
1295
+ }
1296
+ },
1297
+ async flush() {
1298
+ if (timer) clearTimeout(timer);
1299
+ await doFlush();
1300
+ },
1301
+ async close() {
1302
+ await _optionalChain([this, 'access', _42 => _42.flush, 'optionalCall', _43 => _43()]);
1303
+ }
1304
+ };
1305
+ }
1306
+
1307
+ // src/transports/otel.ts
1308
+ var OTEL_SEVERITY_MAP = {
1309
+ TRACE: { number: 1, text: "TRACE" },
1310
+ DEBUG: { number: 5, text: "DEBUG" },
1311
+ INFO: { number: 9, text: "INFO" },
1312
+ WARN: { number: 13, text: "WARN" },
1313
+ ERROR: { number: 17, text: "ERROR" },
1314
+ FATAL: { number: 21, text: "FATAL" }
1315
+ };
1316
+ function otelTransport(options) {
1317
+ const { endpoint, serviceName, level, resource = {} } = options;
1318
+ const batchSize = _nullishCoalesce(options.batchSize, () => ( 20));
1319
+ const interval = _nullishCoalesce(options.interval, () => ( 5e3));
1320
+ const url = `${endpoint.replace(/\/$/, "")}/v1/logs`;
1321
+ const headers = {
1322
+ "Content-Type": "application/json",
1323
+ ...options.headers
1324
+ };
1325
+ const resourceAttributes = [
1326
+ { key: "service.name", value: { stringValue: serviceName } },
1327
+ ...Object.entries(resource).map(([key, val]) => ({
1328
+ key,
1329
+ value: { stringValue: val }
1330
+ }))
1331
+ ];
1332
+ let buffer = [];
1333
+ let timer = null;
1334
+ function toOtlpLogRecord(entry) {
1335
+ const severity = _nullishCoalesce(OTEL_SEVERITY_MAP[entry.levelName], () => ( OTEL_SEVERITY_MAP.INFO));
1336
+ const attributes = [];
1337
+ if (entry.meta && typeof entry.meta === "object") {
1338
+ for (const [key, val] of Object.entries(entry.meta)) {
1339
+ if (key === "traceId" || key === "spanId" || key === "traceFlags")
1340
+ continue;
1341
+ if (val !== void 0 && val !== null) {
1342
+ attributes.push({
1343
+ key,
1344
+ value: typeof val === "number" ? { intValue: val } : { stringValue: String(val) }
1345
+ });
1346
+ }
1347
+ }
1348
+ }
1349
+ if (entry.context) {
1350
+ for (const [key, val] of Object.entries(entry.context)) {
1351
+ if (val !== void 0 && val !== null) {
1352
+ attributes.push({
1353
+ key: `context.${key}`,
1354
+ value: { stringValue: String(val) }
1355
+ });
1356
+ }
1357
+ }
1358
+ }
1359
+ if (entry.error) {
1360
+ attributes.push({
1361
+ key: "error.message",
1362
+ value: { stringValue: entry.error.message }
1363
+ });
1364
+ if (entry.error.name) {
1365
+ attributes.push({
1366
+ key: "error.type",
1367
+ value: { stringValue: entry.error.name }
1368
+ });
1037
1369
  }
1038
- ];
1370
+ if (entry.error.stack) {
1371
+ attributes.push({
1372
+ key: "error.stack",
1373
+ value: { stringValue: entry.error.stack }
1374
+ });
1375
+ }
1376
+ }
1377
+ const record = {
1378
+ timeUnixNano: String(entry.timestamp * 1e6),
1379
+ // ms → ns
1380
+ severityNumber: _optionalChain([severity, 'optionalAccess', _44 => _44.number]),
1381
+ severityText: _optionalChain([severity, 'optionalAccess', _45 => _45.text]),
1382
+ body: { stringValue: entry.message },
1383
+ attributes
1384
+ };
1385
+ const meta = entry.meta;
1386
+ if (_optionalChain([meta, 'optionalAccess', _46 => _46.traceId])) {
1387
+ record.traceId = meta.traceId;
1388
+ }
1389
+ if (_optionalChain([meta, 'optionalAccess', _47 => _47.spanId])) {
1390
+ record.spanId = meta.spanId;
1391
+ }
1392
+ if (_optionalChain([meta, 'optionalAccess', _48 => _48.traceFlags]) !== void 0) {
1393
+ record.flags = meta.traceFlags;
1394
+ }
1395
+ return record;
1396
+ }
1397
+ async function sendBatch(batch) {
1398
+ const payload = {
1399
+ resourceLogs: [
1400
+ {
1401
+ resource: { attributes: resourceAttributes },
1402
+ scopeLogs: [
1403
+ {
1404
+ scope: { name: "voltlog-io" },
1405
+ logRecords: batch.map(toOtlpLogRecord)
1406
+ }
1407
+ ]
1408
+ }
1409
+ ]
1410
+ };
1039
1411
  try {
1040
- await fetch(url, {
1412
+ const response = await fetch(url, {
1041
1413
  method: "POST",
1042
1414
  headers,
1043
- body: JSON.stringify({ streams })
1415
+ body: JSON.stringify(payload)
1044
1416
  });
1417
+ if (!response.ok) {
1418
+ console.error(
1419
+ `[voltlog] OTLP push failed: ${response.status} ${response.statusText}`
1420
+ );
1421
+ }
1045
1422
  } catch (err) {
1046
- console.error("[voltlog] Loki push failed", err);
1423
+ console.error("[voltlog] OTLP push failed", err);
1047
1424
  }
1048
- };
1049
- const schedule = () => {
1425
+ }
1426
+ function flush() {
1427
+ if (buffer.length === 0) return;
1428
+ const batch = buffer;
1429
+ buffer = [];
1430
+ sendBatch(batch).catch(() => {
1431
+ });
1432
+ }
1433
+ function schedule() {
1050
1434
  if (!timer) {
1051
1435
  timer = setTimeout(() => {
1052
1436
  timer = null;
1053
1437
  flush();
1054
1438
  }, interval);
1055
1439
  }
1056
- };
1440
+ }
1057
1441
  return {
1058
- name: "loki",
1442
+ name: "otel",
1059
1443
  level,
1060
1444
  write(entry) {
1061
1445
  buffer.push(entry);
@@ -1069,10 +1453,14 @@ function lokiTransport(options) {
1069
1453
  },
1070
1454
  async flush() {
1071
1455
  if (timer) clearTimeout(timer);
1072
- await flush();
1456
+ timer = null;
1457
+ if (buffer.length === 0) return;
1458
+ const batch = buffer;
1459
+ buffer = [];
1460
+ await sendBatch(batch);
1073
1461
  },
1074
1462
  async close() {
1075
- await this.flush?.();
1463
+ await _optionalChain([this, 'access', _49 => _49.flush, 'optionalCall', _50 => _50()]);
1076
1464
  }
1077
1465
  };
1078
1466
  }
@@ -1113,27 +1501,29 @@ var DIRECTION_ARROWS = {
1113
1501
  OUT: "\u2190"
1114
1502
  };
1115
1503
  function prettyTransport(options = {}) {
1116
- const showTimestamps = options.timestamps ?? true;
1117
- const useColors = options.colors ?? true;
1504
+ const showTimestamps = _nullishCoalesce(options.timestamps, () => ( true));
1505
+ const useColors = _nullishCoalesce(options.colors, () => ( true));
1506
+ const hideMeta = _nullishCoalesce(options.hideMeta, () => ( false));
1507
+ const prettyMeta = _nullishCoalesce(options.prettyMeta, () => ( false));
1118
1508
  function colorize(text, color) {
1119
1509
  return useColors ? `${color}${text}${RESET}` : text;
1120
1510
  }
1121
1511
  function formatExchange(entry) {
1122
1512
  const meta = entry.meta;
1123
1513
  if (!meta || !meta.action || !meta.messageType) return null;
1124
- const icon = EXCHANGE_ICONS[meta.messageType] ?? "\u2022";
1125
- const arrow = DIRECTION_ARROWS[meta.direction ?? "IN"] ?? "\u2192";
1126
- const cpId = meta.chargePointId ?? "unknown";
1514
+ const icon = _nullishCoalesce(EXCHANGE_ICONS[meta.messageType], () => ( "\u2022"));
1515
+ const arrow = _nullishCoalesce(DIRECTION_ARROWS[_nullishCoalesce(meta.direction, () => ( "IN"))], () => ( "\u2192"));
1516
+ const cpId = _nullishCoalesce(meta.chargePointId, () => ( "unknown"));
1127
1517
  const action = meta.action;
1128
1518
  const msgType = meta.messageType;
1129
- const dir = meta.direction ?? "";
1519
+ const dir = _nullishCoalesce(meta.direction, () => ( ""));
1130
1520
  let line = `${icon} ${colorize(cpId, BOLD)} ${arrow} ${colorize(
1131
1521
  action,
1132
1522
  BOLD
1133
1523
  )} [${dir}] ${colorize(msgType, DIM)}`;
1134
1524
  if (meta.status || meta.latencyMs !== void 0) {
1135
1525
  const statusIcon = meta.messageType === "CALLERROR" ? "\u274C" : "\u2714";
1136
- const status = meta.status ?? "";
1526
+ const status = _nullishCoalesce(meta.status, () => ( ""));
1137
1527
  const latency = meta.latencyMs !== void 0 ? `(${meta.latencyMs}ms)` : "";
1138
1528
  line += `
1139
1529
  ${statusIcon} ${status} ${colorize(latency, DIM)}`;
@@ -1141,22 +1531,39 @@ ${statusIcon} ${status} ${colorize(latency, DIM)}`;
1141
1531
  return line;
1142
1532
  }
1143
1533
  function formatStandard(entry) {
1144
- const icon = ICONS[entry.levelName] ?? "\u2022";
1145
- const levelColor = COLORS[entry.levelName] ?? "";
1534
+ const icon = _nullishCoalesce(ICONS[entry.levelName], () => ( "\u2022"));
1535
+ const levelColor = _nullishCoalesce(COLORS[entry.levelName], () => ( ""));
1146
1536
  const level = colorize(entry.levelName.padEnd(5), levelColor);
1147
1537
  const ts = showTimestamps ? `${colorize(new Date(entry.timestamp).toISOString(), DIM)} ` : "";
1148
1538
  let line = `${icon} ${ts}${level} ${entry.message}`;
1149
1539
  if (entry.context && Object.keys(entry.context).length > 0) {
1150
- line += ` ${colorize(JSON.stringify(entry.context), DIM)}`;
1540
+ const kvStr = Object.entries(entry.context).map(
1541
+ ([k, v]) => `${k}:${typeof v === "string" ? v : JSON.stringify(v)}`
1542
+ ).join(" ");
1543
+ line += ` ${colorize(kvStr, DIM)}`;
1151
1544
  }
1152
- if (entry.meta && Object.keys(entry.meta).length > 0) {
1153
- line += ` ${colorize(JSON.stringify(entry.meta), DIM)}`;
1545
+ if (!hideMeta && entry.meta && Object.keys(entry.meta).length > 0) {
1546
+ if (prettyMeta) {
1547
+ const metaEntries = Object.entries(
1548
+ entry.meta
1549
+ );
1550
+ const parts = metaEntries.map(([key, value]) => {
1551
+ const valStr = typeof value === "string" ? value : JSON.stringify(value);
1552
+ return `${colorize(`${key}:`, DIM)}${valStr}`;
1553
+ });
1554
+ line += ` ${parts.join(" ")}`;
1555
+ } else {
1556
+ const kvStr = Object.entries(entry.meta).map(
1557
+ ([k, v]) => `${k}:${typeof v === "string" ? v : JSON.stringify(v)}`
1558
+ ).join(" ");
1559
+ line += ` ${colorize(kvStr, DIM)}`;
1560
+ }
1154
1561
  }
1155
1562
  if (entry.error) {
1156
1563
  line += `
1157
1564
  ${colorize(
1158
- `${entry.error.name ?? "Error"}: ${entry.error.message}`,
1159
- COLORS.ERROR ?? ""
1565
+ `${_nullishCoalesce(entry.error.name, () => ( "Error"))}: ${entry.error.message}`,
1566
+ _nullishCoalesce(COLORS.ERROR, () => ( ""))
1160
1567
  )}`;
1161
1568
  if (entry.error.stack) {
1162
1569
  line += `
@@ -1189,7 +1596,7 @@ ${colorize(entry.error.stack, DIM)}`;
1189
1596
  // src/transports/redis.ts
1190
1597
  function redisTransport(options) {
1191
1598
  const { client, streamKey = "logs", maxLen, level } = options;
1192
- const fieldMapper = options.fieldMapper ?? defaultFieldMapper;
1599
+ const fieldMapper = _nullishCoalesce(options.fieldMapper, () => ( defaultFieldMapper));
1193
1600
  function defaultFieldMapper(entry) {
1194
1601
  return {
1195
1602
  id: entry.id,
@@ -1226,11 +1633,60 @@ function redisTransport(options) {
1226
1633
  };
1227
1634
  }
1228
1635
 
1636
+ // src/transports/ring-buffer.ts
1637
+ function ringBufferTransport(options = {}) {
1638
+ const maxSize = _nullishCoalesce(options.maxSize, () => ( 1e3));
1639
+ const buffer = [];
1640
+ let head = 0;
1641
+ let count = 0;
1642
+ return {
1643
+ name: "ring-buffer",
1644
+ level: options.level,
1645
+ write(entry) {
1646
+ if (count < maxSize) {
1647
+ buffer.push(entry);
1648
+ count++;
1649
+ } else {
1650
+ buffer[head] = entry;
1651
+ }
1652
+ head = (head + 1) % maxSize;
1653
+ },
1654
+ getEntries(query) {
1655
+ let entries;
1656
+ if (count < maxSize) {
1657
+ entries = buffer.slice();
1658
+ } else {
1659
+ entries = [...buffer.slice(head), ...buffer.slice(0, head)];
1660
+ }
1661
+ if (_optionalChain([query, 'optionalAccess', _51 => _51.level])) {
1662
+ const minLevel = resolveLevel(query.level);
1663
+ entries = entries.filter((e) => e.level >= minLevel);
1664
+ }
1665
+ if (_optionalChain([query, 'optionalAccess', _52 => _52.since])) {
1666
+ const since = query.since;
1667
+ entries = entries.filter((e) => e.timestamp >= since);
1668
+ }
1669
+ if (_optionalChain([query, 'optionalAccess', _53 => _53.limit])) {
1670
+ entries = entries.slice(-query.limit);
1671
+ }
1672
+ return entries;
1673
+ },
1674
+ clear() {
1675
+ buffer.length = 0;
1676
+ head = 0;
1677
+ count = 0;
1678
+ },
1679
+ get size() {
1680
+ return count;
1681
+ }
1682
+ };
1683
+ }
1684
+
1229
1685
  // src/transports/sentry.ts
1230
1686
  function sentryTransport(options) {
1231
1687
  const { sentry } = options;
1232
- const errorLevelValue = resolveLevel(options.errorLevel ?? "ERROR");
1233
- const breadcrumbLevelValue = resolveLevel(options.breadcrumbLevel ?? "INFO");
1688
+ const errorLevelValue = resolveLevel(_nullishCoalesce(options.errorLevel, () => ( "ERROR")));
1689
+ const breadcrumbLevelValue = resolveLevel(_nullishCoalesce(options.breadcrumbLevel, () => ( "INFO")));
1234
1690
  return {
1235
1691
  name: "sentry",
1236
1692
  write(entry) {
@@ -1272,7 +1728,7 @@ function slackTransport(options) {
1272
1728
  const { webhookUrl, username, iconEmoji, level } = options;
1273
1729
  return {
1274
1730
  name: "slack",
1275
- level: level ?? "ERROR",
1731
+ level: _nullishCoalesce(level, () => ( "ERROR")),
1276
1732
  // Default to ERROR to prevent spamming
1277
1733
  async write(entry) {
1278
1734
  try {
@@ -1332,7 +1788,7 @@ function formatSlackMessage(entry, username, icon_emoji) {
1332
1788
  }
1333
1789
  });
1334
1790
  }
1335
- if (entry.error?.stack) {
1791
+ if (_optionalChain([entry, 'access', _54 => _54.error, 'optionalAccess', _55 => _55.stack])) {
1336
1792
  blocks.push({
1337
1793
  type: "section",
1338
1794
  text: {
@@ -1382,11 +1838,11 @@ function webhookTransport(options) {
1382
1838
  retry = false,
1383
1839
  maxRetries = 3
1384
1840
  } = options;
1385
- const serialize = options.serializer ?? ((entries) => JSON.stringify({
1841
+ const serialize = _nullishCoalesce(options.serializer, () => ( ((entries) => JSON.stringify({
1386
1842
  entries,
1387
1843
  count: entries.length,
1388
1844
  timestamp: Date.now()
1389
- }));
1845
+ }))));
1390
1846
  let buffer = [];
1391
1847
  let flushTimer = null;
1392
1848
  async function sendBatch(entries, attempt = 0) {
@@ -1404,7 +1860,7 @@ function webhookTransport(options) {
1404
1860
  await new Promise((r) => setTimeout(r, delay));
1405
1861
  return sendBatch(entries, attempt + 1);
1406
1862
  }
1407
- } catch {
1863
+ } catch (e10) {
1408
1864
  if (retry && attempt < maxRetries) {
1409
1865
  const delay = Math.min(1e3 * 2 ** attempt, 3e4);
1410
1866
  await new Promise((r) => setTimeout(r, delay));
@@ -1449,45 +1905,50 @@ function webhookTransport(options) {
1449
1905
  }
1450
1906
  },
1451
1907
  async close() {
1452
- await this.flush?.();
1908
+ await _optionalChain([this, 'access', _56 => _56.flush, 'optionalCall', _57 => _57()]);
1453
1909
  }
1454
1910
  };
1455
1911
  }
1456
- // Annotate the CommonJS export names for ESM import in node:
1457
- 0 && (module.exports = {
1458
- LogLevel,
1459
- LogLevelNameMap,
1460
- LogLevelValueMap,
1461
- aiEnrichmentMiddleware,
1462
- alertMiddleware,
1463
- batchTransport,
1464
- browserJsonStreamTransport,
1465
- consoleTransport,
1466
- correlationIdMiddleware,
1467
- createLogger,
1468
- createMiddleware,
1469
- createOpenAiErrorAnalyzer,
1470
- createTransport,
1471
- datadogTransport,
1472
- deduplicationMiddleware,
1473
- discordTransport,
1474
- fileTransport,
1475
- heapUsageMiddleware,
1476
- ipMiddleware,
1477
- jsonStreamTransport,
1478
- levelOverrideMiddleware,
1479
- lokiTransport,
1480
- ocppMiddleware,
1481
- prettyTransport,
1482
- redactionMiddleware,
1483
- redisTransport,
1484
- resolveLevel,
1485
- samplingMiddleware,
1486
- sentryTransport,
1487
- shouldIncludeStack,
1488
- shouldLog,
1489
- slackTransport,
1490
- userAgentMiddleware,
1491
- webhookTransport
1492
- });
1912
+
1913
+
1914
+
1915
+
1916
+
1917
+
1918
+
1919
+
1920
+
1921
+
1922
+
1923
+
1924
+
1925
+
1926
+
1927
+
1928
+
1929
+
1930
+
1931
+
1932
+
1933
+
1934
+
1935
+
1936
+
1937
+
1938
+
1939
+
1940
+
1941
+
1942
+
1943
+
1944
+
1945
+
1946
+
1947
+
1948
+
1949
+
1950
+
1951
+
1952
+
1953
+ exports.LogLevel = LogLevel; exports.LogLevelNameMap = LogLevelNameMap; exports.LogLevelValueMap = LogLevelValueMap; exports.aiEnrichmentMiddleware = aiEnrichmentMiddleware; exports.alertMiddleware = alertMiddleware; exports.asyncContextMiddleware = asyncContextMiddleware; exports.batchTransport = batchTransport; exports.browserJsonStreamTransport = browserJsonStreamTransport; exports.consoleTransport = consoleTransport; exports.correlationIdMiddleware = correlationIdMiddleware; exports.createHttpLogger = createHttpLogger; exports.createLogger = createLogger; exports.createMiddleware = createMiddleware; exports.createOpenAiErrorAnalyzer = createOpenAiErrorAnalyzer; exports.createTransport = createTransport; exports.datadogTransport = datadogTransport; exports.deduplicationMiddleware = deduplicationMiddleware; exports.discordTransport = discordTransport; exports.fileTransport = fileTransport; exports.heapUsageMiddleware = heapUsageMiddleware; exports.ipMiddleware = ipMiddleware; exports.jsonStreamTransport = jsonStreamTransport; exports.levelOverrideMiddleware = levelOverrideMiddleware; exports.lokiTransport = lokiTransport; exports.nodeHttpMappers = nodeHttpMappers; exports.ocppMiddleware = ocppMiddleware; exports.otelTraceMiddleware = otelTraceMiddleware; exports.otelTransport = otelTransport; exports.prettyTransport = prettyTransport; exports.redactionMiddleware = redactionMiddleware; exports.redisTransport = redisTransport; exports.resolveLevel = resolveLevel; exports.ringBufferTransport = ringBufferTransport; exports.samplingMiddleware = samplingMiddleware; exports.sentryTransport = sentryTransport; exports.shouldIncludeStack = shouldIncludeStack; exports.shouldLog = shouldLog; exports.slackTransport = slackTransport; exports.userAgentMiddleware = userAgentMiddleware; exports.webhookTransport = webhookTransport;
1493
1954
  //# sourceMappingURL=index.js.map