@rawnodes/logger 1.2.0 → 1.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/dist/index.d.mts CHANGED
@@ -1,26 +1,31 @@
1
- import { Logger } from 'winston';
2
-
3
- interface ConsoleConfig {
4
- level: string;
5
- }
1
+ declare const LOG_LEVELS: {
2
+ readonly error: 0;
3
+ readonly warn: 1;
4
+ readonly info: 2;
5
+ readonly http: 3;
6
+ readonly verbose: 4;
7
+ readonly debug: 5;
8
+ readonly silly: 6;
9
+ };
10
+ type LogLevel = keyof typeof LOG_LEVELS;
11
+ declare function isValidLogLevel(level: string): level is LogLevel;
12
+ declare function assertLogLevel(level: string): asserts level is LogLevel;
6
13
  interface FileConfig {
7
14
  dirname: string;
8
15
  filename: string;
9
- level: string;
10
- datePattern: string;
16
+ datePattern?: string;
11
17
  zippedArchive?: boolean;
12
18
  maxSize?: string;
13
19
  maxFiles?: string;
14
20
  }
15
21
  interface LoggerConfig {
16
- level: string;
17
- console: ConsoleConfig;
22
+ level: LogLevel;
18
23
  file?: FileConfig;
19
24
  }
20
25
  type LoggerContext = Record<string, unknown>;
21
26
  interface LevelOverride<TContext extends LoggerContext> {
22
27
  match: Partial<TContext>;
23
- level: string;
28
+ level: LogLevel;
24
29
  }
25
30
 
26
31
  declare class LoggerStore<TContext extends LoggerContext = LoggerContext> {
@@ -29,40 +34,39 @@ declare class LoggerStore<TContext extends LoggerContext = LoggerContext> {
29
34
  run<T>(context: TContext, fn: () => T): T;
30
35
  }
31
36
 
32
- declare class BaseLogger<TContext extends LoggerContext = LoggerContext> {
33
- private winstonLogger;
34
- private defaultLevel;
35
- private store;
36
- private levelOverrides;
37
- constructor(config: LoggerConfig, store?: LoggerStore<TContext>);
37
+ declare class Logger<TContext extends LoggerContext = LoggerContext> {
38
+ private state;
39
+ private context;
40
+ private constructor();
41
+ static create<TContext extends LoggerContext = LoggerContext>(config: LoggerConfig, store?: LoggerStore<TContext>): Logger<TContext>;
42
+ child(context: string): Logger<TContext>;
38
43
  getStore(): LoggerStore<TContext>;
39
- setLevelOverride(match: Partial<TContext>, level: string): void;
44
+ setLevelOverride(match: Partial<TContext>, level: LogLevel): void;
40
45
  removeLevelOverride(match: Partial<TContext>): void;
41
46
  clearLevelOverrides(): void;
42
47
  getLevelOverrides(): LevelOverride<TContext>[];
43
- private getEffectiveLevel;
44
- private matchesContext;
45
- private shouldLog;
46
- getChildLogger(context: string): Logger;
47
48
  profile(id: string, meta?: object): void;
48
- log(message: string, context?: string, meta?: object): void;
49
- error(message: string, error?: Error | unknown, context?: string): void;
50
- warn(message: string, context?: string, meta?: object): void;
51
- debug(message: string, context?: string, meta?: object): void;
52
- info(message: string, context?: string, meta?: object): void;
53
- verbose(message: string, context?: string, meta?: object): void;
49
+ error(message: string, error?: Error | unknown, meta?: object): void;
50
+ warn(message: string, meta?: object): void;
51
+ info(message: string, meta?: object): void;
52
+ http(message: string, meta?: object): void;
53
+ verbose(message: string, meta?: object): void;
54
+ debug(message: string, meta?: object): void;
55
+ silly(message: string, meta?: object): void;
56
+ private log;
54
57
  }
55
58
 
56
59
  interface SingletonLogger<TContext extends LoggerContext> {
57
- getInstance(config?: LoggerConfig): BaseLogger<TContext>;
60
+ init(config: LoggerConfig, store?: LoggerStore<TContext>): Logger<TContext>;
61
+ get(): Logger<TContext>;
62
+ child(context: string): Logger<TContext>;
58
63
  getStore(): LoggerStore<TContext>;
59
- for(context: string): Logger;
60
- setLevelOverride(match: Partial<TContext>, level: string): void;
64
+ setLevelOverride(match: Partial<TContext>, level: LogLevel): void;
61
65
  removeLevelOverride(match: Partial<TContext>): void;
62
66
  getLevelOverrides(): LevelOverride<TContext>[];
63
67
  clearLevelOverrides(): void;
64
68
  }
65
- declare function createSingletonLogger<TContext extends LoggerContext>(): SingletonLogger<TContext>;
69
+ declare function createSingletonLogger<TContext extends LoggerContext = LoggerContext>(): SingletonLogger<TContext>;
66
70
 
67
71
  interface TimingResult {
68
72
  label: string;
@@ -94,4 +98,4 @@ interface MaskSecretsOptions {
94
98
  declare function maskSecrets(obj: unknown, options?: MaskSecretsOptions): unknown;
95
99
  declare function createMasker(options?: MaskSecretsOptions): (obj: unknown) => unknown;
96
100
 
97
- export { BaseLogger, type ConsoleConfig, type FileConfig, type LevelOverride, type LoggerConfig, type LoggerContext, LoggerStore, type MaskSecretsOptions, type RequestIdOptions, type SingletonLogger, type TimingResult, createMasker, createSingletonLogger, extractRequestId, generateRequestId, getOrGenerateRequestId, maskSecrets, measureAsync, measureSync };
101
+ export { type FileConfig, LOG_LEVELS, type LevelOverride, type LogLevel, Logger, type LoggerConfig, type LoggerContext, LoggerStore, type MaskSecretsOptions, type RequestIdOptions, type SingletonLogger, type TimingResult, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, measureAsync, measureSync };
package/dist/index.d.ts CHANGED
@@ -1,26 +1,31 @@
1
- import { Logger } from 'winston';
2
-
3
- interface ConsoleConfig {
4
- level: string;
5
- }
1
+ declare const LOG_LEVELS: {
2
+ readonly error: 0;
3
+ readonly warn: 1;
4
+ readonly info: 2;
5
+ readonly http: 3;
6
+ readonly verbose: 4;
7
+ readonly debug: 5;
8
+ readonly silly: 6;
9
+ };
10
+ type LogLevel = keyof typeof LOG_LEVELS;
11
+ declare function isValidLogLevel(level: string): level is LogLevel;
12
+ declare function assertLogLevel(level: string): asserts level is LogLevel;
6
13
  interface FileConfig {
7
14
  dirname: string;
8
15
  filename: string;
9
- level: string;
10
- datePattern: string;
16
+ datePattern?: string;
11
17
  zippedArchive?: boolean;
12
18
  maxSize?: string;
13
19
  maxFiles?: string;
14
20
  }
15
21
  interface LoggerConfig {
16
- level: string;
17
- console: ConsoleConfig;
22
+ level: LogLevel;
18
23
  file?: FileConfig;
19
24
  }
20
25
  type LoggerContext = Record<string, unknown>;
21
26
  interface LevelOverride<TContext extends LoggerContext> {
22
27
  match: Partial<TContext>;
23
- level: string;
28
+ level: LogLevel;
24
29
  }
25
30
 
26
31
  declare class LoggerStore<TContext extends LoggerContext = LoggerContext> {
@@ -29,40 +34,39 @@ declare class LoggerStore<TContext extends LoggerContext = LoggerContext> {
29
34
  run<T>(context: TContext, fn: () => T): T;
30
35
  }
31
36
 
32
- declare class BaseLogger<TContext extends LoggerContext = LoggerContext> {
33
- private winstonLogger;
34
- private defaultLevel;
35
- private store;
36
- private levelOverrides;
37
- constructor(config: LoggerConfig, store?: LoggerStore<TContext>);
37
+ declare class Logger<TContext extends LoggerContext = LoggerContext> {
38
+ private state;
39
+ private context;
40
+ private constructor();
41
+ static create<TContext extends LoggerContext = LoggerContext>(config: LoggerConfig, store?: LoggerStore<TContext>): Logger<TContext>;
42
+ child(context: string): Logger<TContext>;
38
43
  getStore(): LoggerStore<TContext>;
39
- setLevelOverride(match: Partial<TContext>, level: string): void;
44
+ setLevelOverride(match: Partial<TContext>, level: LogLevel): void;
40
45
  removeLevelOverride(match: Partial<TContext>): void;
41
46
  clearLevelOverrides(): void;
42
47
  getLevelOverrides(): LevelOverride<TContext>[];
43
- private getEffectiveLevel;
44
- private matchesContext;
45
- private shouldLog;
46
- getChildLogger(context: string): Logger;
47
48
  profile(id: string, meta?: object): void;
48
- log(message: string, context?: string, meta?: object): void;
49
- error(message: string, error?: Error | unknown, context?: string): void;
50
- warn(message: string, context?: string, meta?: object): void;
51
- debug(message: string, context?: string, meta?: object): void;
52
- info(message: string, context?: string, meta?: object): void;
53
- verbose(message: string, context?: string, meta?: object): void;
49
+ error(message: string, error?: Error | unknown, meta?: object): void;
50
+ warn(message: string, meta?: object): void;
51
+ info(message: string, meta?: object): void;
52
+ http(message: string, meta?: object): void;
53
+ verbose(message: string, meta?: object): void;
54
+ debug(message: string, meta?: object): void;
55
+ silly(message: string, meta?: object): void;
56
+ private log;
54
57
  }
55
58
 
56
59
  interface SingletonLogger<TContext extends LoggerContext> {
57
- getInstance(config?: LoggerConfig): BaseLogger<TContext>;
60
+ init(config: LoggerConfig, store?: LoggerStore<TContext>): Logger<TContext>;
61
+ get(): Logger<TContext>;
62
+ child(context: string): Logger<TContext>;
58
63
  getStore(): LoggerStore<TContext>;
59
- for(context: string): Logger;
60
- setLevelOverride(match: Partial<TContext>, level: string): void;
64
+ setLevelOverride(match: Partial<TContext>, level: LogLevel): void;
61
65
  removeLevelOverride(match: Partial<TContext>): void;
62
66
  getLevelOverrides(): LevelOverride<TContext>[];
63
67
  clearLevelOverrides(): void;
64
68
  }
65
- declare function createSingletonLogger<TContext extends LoggerContext>(): SingletonLogger<TContext>;
69
+ declare function createSingletonLogger<TContext extends LoggerContext = LoggerContext>(): SingletonLogger<TContext>;
66
70
 
67
71
  interface TimingResult {
68
72
  label: string;
@@ -94,4 +98,4 @@ interface MaskSecretsOptions {
94
98
  declare function maskSecrets(obj: unknown, options?: MaskSecretsOptions): unknown;
95
99
  declare function createMasker(options?: MaskSecretsOptions): (obj: unknown) => unknown;
96
100
 
97
- export { BaseLogger, type ConsoleConfig, type FileConfig, type LevelOverride, type LoggerConfig, type LoggerContext, LoggerStore, type MaskSecretsOptions, type RequestIdOptions, type SingletonLogger, type TimingResult, createMasker, createSingletonLogger, extractRequestId, generateRequestId, getOrGenerateRequestId, maskSecrets, measureAsync, measureSync };
101
+ export { type FileConfig, LOG_LEVELS, type LevelOverride, type LogLevel, Logger, type LoggerConfig, type LoggerContext, LoggerStore, type MaskSecretsOptions, type RequestIdOptions, type SingletonLogger, type TimingResult, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, measureAsync, measureSync };
package/dist/index.js CHANGED
@@ -1,16 +1,25 @@
1
1
  'use strict';
2
2
 
3
3
  var winston = require('winston');
4
+ var async_hooks = require('async_hooks');
4
5
  var util = require('util');
5
6
  var DailyRotateFile = require('winston-daily-rotate-file');
6
- var async_hooks = require('async_hooks');
7
7
  var crypto = require('crypto');
8
8
 
9
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
10
 
11
11
  var DailyRotateFile__default = /*#__PURE__*/_interopDefault(DailyRotateFile);
12
12
 
13
- // src/logger.ts
13
+ // src/state.ts
14
+ var LoggerStore = class {
15
+ storage = new async_hooks.AsyncLocalStorage();
16
+ getStore() {
17
+ return this.storage.getStore();
18
+ }
19
+ run(context, fn) {
20
+ return this.storage.run(context, fn);
21
+ }
22
+ };
14
23
 
15
24
  // src/utils/mask-secrets.ts
16
25
  var DEFAULT_SECRET_PATTERNS = [
@@ -59,6 +68,9 @@ function maskSecrets(obj, options = {}) {
59
68
  }
60
69
  if (typeof obj === "object") {
61
70
  const result = {};
71
+ for (const sym of Object.getOwnPropertySymbols(obj)) {
72
+ result[sym] = obj[sym];
73
+ }
62
74
  for (const [key, value] of Object.entries(obj)) {
63
75
  if (isSecretKey(key, patterns)) {
64
76
  result[key] = mask;
@@ -152,21 +164,16 @@ function createFormat(isLocal, store) {
152
164
  return isLocal ? createLocalFormat(store) : createProductionFormat(store);
153
165
  }
154
166
  function createTransports(config) {
155
- const result = [
156
- new winston.transports.Console({
157
- level: config.console.level
158
- })
159
- ];
167
+ const result = [new winston.transports.Console()];
160
168
  if (config.file) {
161
169
  result.push(
162
170
  new DailyRotateFile__default.default({
163
171
  dirname: config.file.dirname,
164
172
  filename: config.file.filename,
165
- level: config.file.level,
166
- datePattern: config.file.datePattern,
167
- zippedArchive: config.file.zippedArchive,
168
- maxSize: config.file.maxSize,
169
- maxFiles: config.file.maxFiles
173
+ datePattern: config.file.datePattern ?? "YYYY-MM-DD",
174
+ zippedArchive: config.file.zippedArchive ?? false,
175
+ maxSize: config.file.maxSize ?? "20m",
176
+ maxFiles: config.file.maxFiles ?? "14d"
170
177
  })
171
178
  );
172
179
  }
@@ -178,28 +185,18 @@ function createExceptionHandlers(config) {
178
185
  result.push(
179
186
  new DailyRotateFile__default.default({
180
187
  dirname: config.file.dirname,
181
- filename: config.file.filename,
182
- datePattern: config.file.datePattern,
183
- zippedArchive: config.file.zippedArchive,
184
- maxSize: config.file.maxSize,
185
- maxFiles: config.file.maxFiles
188
+ filename: `exceptions-${config.file.filename}`,
189
+ datePattern: config.file.datePattern ?? "YYYY-MM-DD",
190
+ zippedArchive: config.file.zippedArchive ?? false,
191
+ maxSize: config.file.maxSize ?? "20m",
192
+ maxFiles: config.file.maxFiles ?? "14d"
186
193
  })
187
194
  );
188
195
  }
189
196
  return result;
190
197
  }
191
- var LoggerStore = class {
192
- storage = new async_hooks.AsyncLocalStorage();
193
- getStore() {
194
- return this.storage.getStore();
195
- }
196
- run(context, fn) {
197
- return this.storage.run(context, fn);
198
- }
199
- };
200
198
 
201
- // src/logger.ts
202
- var DEFAULT_CONTEXT2 = "APP";
199
+ // src/types.ts
203
200
  var LOG_LEVELS = {
204
201
  error: 0,
205
202
  warn: 1,
@@ -209,135 +206,169 @@ var LOG_LEVELS = {
209
206
  debug: 5,
210
207
  silly: 6
211
208
  };
212
- var BaseLogger = class {
213
- winstonLogger;
214
- defaultLevel;
215
- store;
216
- levelOverrides = /* @__PURE__ */ new Map();
217
- constructor(config, store) {
218
- const isLocal = process.env.NODE_ENV !== "production";
219
- this.defaultLevel = config.level;
220
- this.store = store ?? new LoggerStore();
221
- const exceptionHandlers = createExceptionHandlers(config);
222
- this.winstonLogger = winston.createLogger({
223
- level: "silly",
224
- // Allow all, we filter manually
225
- format: createFormat(isLocal, this.store),
226
- transports: createTransports(config),
227
- exceptionHandlers,
228
- rejectionHandlers: exceptionHandlers,
229
- exitOnError: false
230
- });
209
+ function isValidLogLevel(level) {
210
+ return level in LOG_LEVELS;
211
+ }
212
+ function assertLogLevel(level) {
213
+ if (!isValidLogLevel(level)) {
214
+ throw new Error(`Invalid log level: "${level}". Valid levels: ${Object.keys(LOG_LEVELS).join(", ")}`);
231
215
  }
216
+ }
217
+
218
+ // src/state.ts
219
+ function createState(config, store) {
220
+ assertLogLevel(config.level);
221
+ const loggerStore = store ?? new LoggerStore();
222
+ const isLocal = process.env.NODE_ENV !== "production";
223
+ const exceptionHandlers = createExceptionHandlers(config);
224
+ const winston$1 = winston.createLogger({
225
+ level: "silly",
226
+ // Accept all, we filter in shouldLog()
227
+ format: createFormat(isLocal, loggerStore),
228
+ transports: createTransports(config),
229
+ exceptionHandlers,
230
+ rejectionHandlers: exceptionHandlers,
231
+ exitOnError: false
232
+ });
233
+ return {
234
+ winston: winston$1,
235
+ store: loggerStore,
236
+ defaultLevel: config.level,
237
+ levelOverrides: /* @__PURE__ */ new Map()
238
+ };
239
+ }
240
+ function shouldLog(state, level) {
241
+ const effectiveLevel = getEffectiveLevel(state);
242
+ return LOG_LEVELS[level] <= LOG_LEVELS[effectiveLevel];
243
+ }
244
+ function getEffectiveLevel(state) {
245
+ const context = state.store.getStore();
246
+ if (!context) return state.defaultLevel;
247
+ for (const { match, level } of state.levelOverrides.values()) {
248
+ if (matchesContext(context, match)) {
249
+ return level;
250
+ }
251
+ }
252
+ return state.defaultLevel;
253
+ }
254
+ function matchesContext(context, match) {
255
+ return Object.entries(match).every(([key, value]) => context[key] === value);
256
+ }
257
+
258
+ // src/logger.ts
259
+ var Logger = class _Logger {
260
+ constructor(state, context) {
261
+ this.state = state;
262
+ this.context = context;
263
+ }
264
+ static create(config, store) {
265
+ const state = createState(config, store);
266
+ return new _Logger(state, "APP");
267
+ }
268
+ child(context) {
269
+ return new _Logger(this.state, context);
270
+ }
271
+ // State accessors
232
272
  getStore() {
233
- return this.store;
273
+ return this.state.store;
234
274
  }
235
275
  setLevelOverride(match, level) {
276
+ assertLogLevel(level);
236
277
  const key = JSON.stringify(match);
237
- this.levelOverrides.set(key, { match, level });
278
+ this.state.levelOverrides.set(key, { match, level });
238
279
  }
239
280
  removeLevelOverride(match) {
240
281
  const key = JSON.stringify(match);
241
- this.levelOverrides.delete(key);
282
+ this.state.levelOverrides.delete(key);
242
283
  }
243
284
  clearLevelOverrides() {
244
- this.levelOverrides.clear();
285
+ this.state.levelOverrides.clear();
245
286
  }
246
287
  getLevelOverrides() {
247
- return Array.from(this.levelOverrides.values());
288
+ return Array.from(this.state.levelOverrides.values());
248
289
  }
249
- getEffectiveLevel() {
250
- const context = this.store.getStore();
251
- if (!context) return this.defaultLevel;
252
- for (const { match, level } of this.levelOverrides.values()) {
253
- if (this.matchesContext(context, match)) {
254
- return level;
255
- }
256
- }
257
- return this.defaultLevel;
290
+ // Profiling
291
+ profile(id, meta) {
292
+ this.state.winston.profile(id, meta);
258
293
  }
259
- matchesContext(context, match) {
260
- return Object.entries(match).every(([key, value]) => context[key] === value);
294
+ // Logging methods
295
+ error(message, error, meta) {
296
+ if (!shouldLog(this.state, "error")) return;
297
+ this.log("error", message, meta, error);
261
298
  }
262
- shouldLog(level) {
263
- const effectiveLevel = this.getEffectiveLevel();
264
- return LOG_LEVELS[level] <= LOG_LEVELS[effectiveLevel];
299
+ warn(message, meta) {
300
+ if (!shouldLog(this.state, "warn")) return;
301
+ this.log("warn", message, meta);
265
302
  }
266
- getChildLogger(context) {
267
- return this.winstonLogger.child({ context });
303
+ info(message, meta) {
304
+ if (!shouldLog(this.state, "info")) return;
305
+ this.log("info", message, meta);
268
306
  }
269
- profile(id, meta) {
270
- this.winstonLogger.profile(id, meta);
307
+ http(message, meta) {
308
+ if (!shouldLog(this.state, "http")) return;
309
+ this.log("http", message, meta);
271
310
  }
272
- log(message, context, meta) {
273
- if (!this.shouldLog("info")) return;
274
- this.winstonLogger.info(message, { context: context || DEFAULT_CONTEXT2, ...meta });
275
- }
276
- error(message, error, context) {
277
- if (!this.shouldLog("error")) return;
278
- const meta = { context: context || DEFAULT_CONTEXT2 };
279
- if (error instanceof Error) {
280
- meta.errorMessage = error.message;
281
- meta.errorStack = error.stack;
282
- } else if (error) {
283
- meta.error = error;
284
- }
285
- this.winstonLogger.error(message, meta);
311
+ verbose(message, meta) {
312
+ if (!shouldLog(this.state, "verbose")) return;
313
+ this.log("verbose", message, meta);
286
314
  }
287
- warn(message, context, meta) {
288
- if (!this.shouldLog("warn")) return;
289
- this.winstonLogger.warn(message, { context: context || DEFAULT_CONTEXT2, ...meta });
315
+ debug(message, meta) {
316
+ if (!shouldLog(this.state, "debug")) return;
317
+ this.log("debug", message, meta);
290
318
  }
291
- debug(message, context, meta) {
292
- if (!this.shouldLog("debug")) return;
293
- this.winstonLogger.debug(message, { context: context || DEFAULT_CONTEXT2, ...meta });
319
+ silly(message, meta) {
320
+ if (!shouldLog(this.state, "silly")) return;
321
+ this.log("silly", message, meta);
294
322
  }
295
- info(message, context, meta) {
296
- if (!this.shouldLog("info")) return;
297
- this.winstonLogger.info(message, { context: context || DEFAULT_CONTEXT2, ...meta });
298
- }
299
- verbose(message, context, meta) {
300
- if (!this.shouldLog("verbose")) return;
301
- this.winstonLogger.verbose(message, { context: context || DEFAULT_CONTEXT2, ...meta });
323
+ // Private
324
+ log(level, message, meta, error) {
325
+ const logMeta = { context: this.context, ...meta };
326
+ if (error instanceof Error) {
327
+ logMeta.errorMessage = error.message;
328
+ logMeta.stack = error.stack;
329
+ } else if (error !== void 0) {
330
+ logMeta.error = error;
331
+ }
332
+ this.state.winston.log(level, message, logMeta);
302
333
  }
303
334
  };
304
335
 
305
336
  // src/singleton.ts
306
337
  function createSingletonLogger() {
307
- let instance = null;
308
- const ensureInstance = () => {
309
- if (!instance) {
310
- throw new Error("Logger not initialized. Call getInstance(config) first.");
338
+ let root = null;
339
+ const ensureInit = () => {
340
+ if (!root) {
341
+ throw new Error("Logger not initialized. Call init(config) first.");
311
342
  }
312
- return instance;
343
+ return root;
313
344
  };
314
345
  return {
315
- getInstance(config) {
316
- if (!instance) {
317
- if (!config) {
318
- throw new Error("Logger config is required for first initialization");
319
- }
320
- instance = new BaseLogger(config);
346
+ init(config, store) {
347
+ if (!root) {
348
+ root = Logger.create(config, store);
321
349
  }
322
- return instance;
350
+ return root;
323
351
  },
324
- getStore() {
325
- return ensureInstance().getStore();
352
+ get() {
353
+ return ensureInit();
354
+ },
355
+ child(context) {
356
+ return ensureInit().child(context);
326
357
  },
327
- for(context) {
328
- return ensureInstance().getChildLogger(context);
358
+ getStore() {
359
+ return ensureInit().getStore();
329
360
  },
330
361
  setLevelOverride(match, level) {
331
- ensureInstance().setLevelOverride(match, level);
362
+ ensureInit().setLevelOverride(match, level);
332
363
  },
333
364
  removeLevelOverride(match) {
334
- ensureInstance().removeLevelOverride(match);
365
+ ensureInit().removeLevelOverride(match);
335
366
  },
336
367
  getLevelOverrides() {
337
- return ensureInstance().getLevelOverrides();
368
+ return ensureInit().getLevelOverrides();
338
369
  },
339
370
  clearLevelOverrides() {
340
- ensureInstance().clearLevelOverrides();
371
+ ensureInit().clearLevelOverrides();
341
372
  }
342
373
  };
343
374
  }
@@ -402,13 +433,16 @@ function getOrGenerateRequestId(headers, options = {}) {
402
433
  return extractRequestId(headers) ?? generateRequestId(options);
403
434
  }
404
435
 
405
- exports.BaseLogger = BaseLogger;
436
+ exports.LOG_LEVELS = LOG_LEVELS;
437
+ exports.Logger = Logger;
406
438
  exports.LoggerStore = LoggerStore;
439
+ exports.assertLogLevel = assertLogLevel;
407
440
  exports.createMasker = createMasker;
408
441
  exports.createSingletonLogger = createSingletonLogger;
409
442
  exports.extractRequestId = extractRequestId;
410
443
  exports.generateRequestId = generateRequestId;
411
444
  exports.getOrGenerateRequestId = getOrGenerateRequestId;
445
+ exports.isValidLogLevel = isValidLogLevel;
412
446
  exports.maskSecrets = maskSecrets;
413
447
  exports.measureAsync = measureAsync;
414
448
  exports.measureSync = measureSync;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/mask-secrets.ts","../src/formatters.ts","../src/transports.ts","../src/store.ts","../src/logger.ts","../src/singleton.ts","../src/utils/timing.ts","../src/utils/request-id.ts"],"names":["inspect","format","transports","DailyRotateFile","AsyncLocalStorage","DEFAULT_CONTEXT","createLogger","randomUUID"],"mappings":"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","file":"index.js","sourcesContent":["const DEFAULT_SECRET_PATTERNS = [\n 'password',\n 'secret',\n 'token',\n 'apikey',\n 'api_key',\n 'api-key',\n 'auth',\n 'credential',\n 'private',\n];\n\nconst DEFAULT_MASK = '***';\n\nexport interface MaskSecretsOptions {\n patterns?: string[];\n mask?: string;\n deep?: boolean;\n}\n\nfunction isSecretKey(key: string, patterns: string[]): boolean {\n const lowerKey = key.toLowerCase();\n return patterns.some((pattern) => lowerKey.includes(pattern.toLowerCase()));\n}\n\nfunction maskUrlCredentials(url: string, mask: string): string {\n try {\n const parsed = new URL(url);\n if (parsed.password) {\n parsed.password = mask;\n }\n if (parsed.username && parsed.password) {\n parsed.username = mask;\n }\n return parsed.toString();\n } catch {\n return url;\n }\n}\n\nexport function maskSecrets(\n obj: unknown,\n options: MaskSecretsOptions = {},\n): unknown {\n const { patterns = DEFAULT_SECRET_PATTERNS, mask = DEFAULT_MASK, deep = true } = options;\n\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (typeof obj === 'string') {\n if (obj.startsWith('http://') || obj.startsWith('https://')) {\n return maskUrlCredentials(obj, mask);\n }\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return deep ? obj.map((item) => maskSecrets(item, options)) : obj;\n }\n\n if (typeof obj === 'object') {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n if (isSecretKey(key, patterns)) {\n result[key] = mask;\n } else if (deep && typeof value === 'object' && value !== null) {\n result[key] = maskSecrets(value, options);\n } else if (typeof value === 'string') {\n result[key] = maskSecrets(value, options);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n }\n\n return obj;\n}\n\nexport function createMasker(options: MaskSecretsOptions = {}) {\n return (obj: unknown): unknown => maskSecrets(obj, options);\n}\n","import { inspect } from 'util';\nimport { format, Logform } from 'winston';\nimport { LoggerStore } from './store.js';\nimport type { LoggerContext } from './types.js';\nimport { maskSecrets, type MaskSecretsOptions } from './utils/mask-secrets.js';\n\nconst DEFAULT_CONTEXT = 'APP';\n\nconst LEVEL_COLORS: Record<string, string> = {\n error: '\\x1b[31m', // red\n warn: '\\x1b[33m', // yellow\n info: '\\x1b[32m', // green\n http: '\\x1b[35m', // magenta\n verbose: '\\x1b[36m', // cyan\n debug: '\\x1b[34m', // blue\n silly: '\\x1b[90m', // grey\n};\nconst RESET = '\\x1b[0m';\n\nfunction colorizeLevel(level: string): string {\n const color = LEVEL_COLORS[level] || '';\n return color ? `${color}${level}${RESET}` : level;\n}\n\nfunction formatMeta(meta: Record<string, unknown>, colors: boolean): string {\n return Object.entries(meta)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => {\n if (typeof value === 'object') {\n const inspected = inspect(value, { depth: 4, colors, compact: false });\n return `\\n ${key}: ${inspected.split('\\n').join('\\n ')}`;\n }\n return `\\n ${key}: ${value}`;\n })\n .join('');\n}\n\nfunction addStoreContext<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format((info) => {\n const storeContext = store.getStore();\n if (storeContext) {\n return { ...info, ...storeContext };\n }\n return info;\n })();\n}\n\nfunction maskSecretsFormat(options?: MaskSecretsOptions): Logform.Format {\n return format((info) => {\n return maskSecrets(info, options) as Logform.TransformableInfo;\n })();\n}\n\nexport function createLocalFormat<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format.combine(\n format.errors({ stack: true }),\n format.timestamp(),\n addStoreContext(store),\n maskSecretsFormat(),\n format.printf(({ timestamp, level, context, message, ...meta }) => {\n const formattedMeta = formatMeta(meta, true);\n const coloredLevel = colorizeLevel(level);\n return `[${timestamp}] ${coloredLevel} [${context || DEFAULT_CONTEXT}] ${message}${formattedMeta}`;\n }),\n );\n}\n\nexport function createProductionFormat<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format.combine(\n format.errors({ stack: true }),\n format.timestamp(),\n addStoreContext(store),\n maskSecretsFormat(),\n format.json(),\n );\n}\n\nexport function createFormat<TContext extends LoggerContext>(isLocal: boolean, store: LoggerStore<TContext>): Logform.Format {\n return isLocal ? createLocalFormat(store) : createProductionFormat(store);\n}\n","import { transports } from 'winston';\nimport DailyRotateFile from 'winston-daily-rotate-file';\nimport { LoggerConfig } from './types.js';\n\ntype Transport = transports.ConsoleTransportInstance | DailyRotateFile;\n\nexport function createTransports(config: LoggerConfig): Transport[] {\n const result: Transport[] = [\n new transports.Console({\n level: config.console.level,\n }),\n ];\n\n if (config.file) {\n result.push(\n new DailyRotateFile({\n dirname: config.file.dirname,\n filename: config.file.filename,\n level: config.file.level,\n datePattern: config.file.datePattern,\n zippedArchive: config.file.zippedArchive,\n maxSize: config.file.maxSize,\n maxFiles: config.file.maxFiles,\n }),\n );\n }\n\n return result;\n}\n\nexport function createExceptionHandlers(config: LoggerConfig): Transport[] {\n const result: Transport[] = [new transports.Console()];\n\n if (config.file) {\n result.push(\n new DailyRotateFile({\n dirname: config.file.dirname,\n filename: config.file.filename,\n datePattern: config.file.datePattern,\n zippedArchive: config.file.zippedArchive,\n maxSize: config.file.maxSize,\n maxFiles: config.file.maxFiles,\n }),\n );\n }\n\n return result;\n}\n","import { AsyncLocalStorage } from 'async_hooks';\nimport type { LoggerContext } from './types.js';\n\nexport class LoggerStore<TContext extends LoggerContext = LoggerContext> {\n private storage = new AsyncLocalStorage<TContext>();\n\n getStore(): TContext | undefined {\n return this.storage.getStore();\n }\n\n run<T>(context: TContext, fn: () => T): T {\n return this.storage.run(context, fn);\n }\n}\n","import { createLogger, Logger } from 'winston';\nimport type { LoggerConfig, LoggerContext, LevelOverride } from './types.js';\nimport { createFormat } from './formatters.js';\nimport { createTransports, createExceptionHandlers } from './transports.js';\nimport { LoggerStore } from './store.js';\n\nconst DEFAULT_CONTEXT = 'APP';\n\nconst LOG_LEVELS: Record<string, number> = {\n error: 0,\n warn: 1,\n info: 2,\n http: 3,\n verbose: 4,\n debug: 5,\n silly: 6,\n};\n\nexport class BaseLogger<TContext extends LoggerContext = LoggerContext> {\n private winstonLogger: Logger;\n private defaultLevel: string;\n private store: LoggerStore<TContext>;\n private levelOverrides: Map<string, LevelOverride<TContext>> = new Map();\n\n constructor(config: LoggerConfig, store?: LoggerStore<TContext>) {\n const isLocal = process.env.NODE_ENV !== 'production';\n\n this.defaultLevel = config.level;\n this.store = store ?? new LoggerStore<TContext>();\n\n const exceptionHandlers = createExceptionHandlers(config);\n\n this.winstonLogger = createLogger({\n level: 'silly', // Allow all, we filter manually\n format: createFormat(isLocal, this.store),\n transports: createTransports(config),\n exceptionHandlers,\n rejectionHandlers: exceptionHandlers,\n exitOnError: false,\n });\n }\n\n getStore(): LoggerStore<TContext> {\n return this.store;\n }\n\n setLevelOverride(match: Partial<TContext>, level: string): void {\n const key = JSON.stringify(match);\n this.levelOverrides.set(key, { match, level });\n }\n\n removeLevelOverride(match: Partial<TContext>): void {\n const key = JSON.stringify(match);\n this.levelOverrides.delete(key);\n }\n\n clearLevelOverrides(): void {\n this.levelOverrides.clear();\n }\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return Array.from(this.levelOverrides.values());\n }\n\n private getEffectiveLevel(): string {\n const context = this.store.getStore();\n if (!context) return this.defaultLevel;\n\n for (const { match, level } of this.levelOverrides.values()) {\n if (this.matchesContext(context, match)) {\n return level;\n }\n }\n return this.defaultLevel;\n }\n\n private matchesContext(context: TContext, match: Partial<TContext>): boolean {\n return Object.entries(match).every(([key, value]) => context[key] === value);\n }\n\n private shouldLog(level: string): boolean {\n const effectiveLevel = this.getEffectiveLevel();\n return LOG_LEVELS[level] <= LOG_LEVELS[effectiveLevel];\n }\n\n getChildLogger(context: string): Logger {\n return this.winstonLogger.child({ context });\n }\n\n profile(id: string, meta?: object): void {\n this.winstonLogger.profile(id, meta);\n }\n\n log(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('info')) return;\n this.winstonLogger.info(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n\n error(message: string, error?: Error | unknown, context?: string): void {\n if (!this.shouldLog('error')) return;\n const meta: Record<string, unknown> = { context: context || DEFAULT_CONTEXT };\n if (error instanceof Error) {\n meta.errorMessage = error.message;\n meta.errorStack = error.stack;\n } else if (error) {\n meta.error = error;\n }\n this.winstonLogger.error(message, meta);\n }\n\n warn(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('warn')) return;\n this.winstonLogger.warn(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n\n debug(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('debug')) return;\n this.winstonLogger.debug(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n\n info(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('info')) return;\n this.winstonLogger.info(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n\n verbose(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('verbose')) return;\n this.winstonLogger.verbose(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n}\n","import { Logger } from 'winston';\nimport { BaseLogger } from './logger.js';\nimport { LoggerStore } from './store.js';\nimport type { LoggerConfig, LoggerContext, LevelOverride } from './types.js';\n\nexport interface SingletonLogger<TContext extends LoggerContext> {\n getInstance(config?: LoggerConfig): BaseLogger<TContext>;\n getStore(): LoggerStore<TContext>;\n for(context: string): Logger;\n setLevelOverride(match: Partial<TContext>, level: string): void;\n removeLevelOverride(match: Partial<TContext>): void;\n getLevelOverrides(): LevelOverride<TContext>[];\n clearLevelOverrides(): void;\n}\n\nexport function createSingletonLogger<TContext extends LoggerContext>(): SingletonLogger<TContext> {\n let instance: BaseLogger<TContext> | null = null;\n\n const ensureInstance = (): BaseLogger<TContext> => {\n if (!instance) {\n throw new Error('Logger not initialized. Call getInstance(config) first.');\n }\n return instance;\n };\n\n return {\n getInstance(config?: LoggerConfig): BaseLogger<TContext> {\n if (!instance) {\n if (!config) {\n throw new Error('Logger config is required for first initialization');\n }\n instance = new BaseLogger<TContext>(config);\n }\n return instance;\n },\n\n getStore(): LoggerStore<TContext> {\n return ensureInstance().getStore();\n },\n\n for(context: string): Logger {\n return ensureInstance().getChildLogger(context);\n },\n\n setLevelOverride(match: Partial<TContext>, level: string): void {\n ensureInstance().setLevelOverride(match, level);\n },\n\n removeLevelOverride(match: Partial<TContext>): void {\n ensureInstance().removeLevelOverride(match);\n },\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return ensureInstance().getLevelOverrides();\n },\n\n clearLevelOverrides(): void {\n ensureInstance().clearLevelOverrides();\n },\n };\n}\n","export interface TimingResult {\n label: string;\n durationMs: number;\n durationFormatted: string;\n}\n\nexport interface Timer {\n end: () => TimingResult;\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms.toFixed(2)}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(1);\n return `${minutes}m ${seconds}s`;\n}\n\nexport function createTimer(label: string): Timer {\n const start = performance.now();\n\n return {\n end(): TimingResult {\n const durationMs = performance.now() - start;\n return {\n label,\n durationMs,\n durationFormatted: formatDuration(durationMs),\n };\n },\n };\n}\n\nexport async function measureAsync<T>(\n label: string,\n fn: () => Promise<T>,\n): Promise<{ result: T; timing: TimingResult }> {\n const timer = createTimer(label);\n const result = await fn();\n const timing = timer.end();\n return { result, timing };\n}\n\nexport function measureSync<T>(\n label: string,\n fn: () => T,\n): { result: T; timing: TimingResult } {\n const timer = createTimer(label);\n const result = fn();\n const timing = timer.end();\n return { result, timing };\n}\n","import { randomUUID } from 'crypto';\n\nexport interface RequestIdOptions {\n prefix?: string;\n short?: boolean;\n}\n\nexport function generateRequestId(options: RequestIdOptions = {}): string {\n const { prefix, short = false } = options;\n const uuid = randomUUID();\n const id = short ? uuid.split('-')[0] : uuid;\n return prefix ? `${prefix}-${id}` : id;\n}\n\nexport function extractRequestId(headers: Record<string, string | string[] | undefined>): string | undefined {\n const headerNames = ['x-request-id', 'x-correlation-id', 'x-trace-id'];\n\n for (const name of headerNames) {\n const value = headers[name];\n if (typeof value === 'string' && value.length > 0) {\n return value;\n }\n if (Array.isArray(value) && value.length > 0) {\n return value[0];\n }\n }\n\n return undefined;\n}\n\nexport function getOrGenerateRequestId(\n headers: Record<string, string | string[] | undefined>,\n options: RequestIdOptions = {},\n): string {\n return extractRequestId(headers) ?? generateRequestId(options);\n}\n"]}
1
+ {"version":3,"sources":["../src/store.ts","../src/utils/mask-secrets.ts","../src/formatters.ts","../src/transports.ts","../src/types.ts","../src/state.ts","../src/logger.ts","../src/singleton.ts","../src/utils/timing.ts","../src/utils/request-id.ts"],"names":["AsyncLocalStorage","inspect","format","transports","DailyRotateFile","winston","createLogger","randomUUID"],"mappings":"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","file":"index.js","sourcesContent":["import { AsyncLocalStorage } from 'async_hooks';\nimport type { LoggerContext } from './types.js';\n\nexport class LoggerStore<TContext extends LoggerContext = LoggerContext> {\n private storage = new AsyncLocalStorage<TContext>();\n\n getStore(): TContext | undefined {\n return this.storage.getStore();\n }\n\n run<T>(context: TContext, fn: () => T): T {\n return this.storage.run(context, fn);\n }\n}\n","const DEFAULT_SECRET_PATTERNS = [\n 'password',\n 'secret',\n 'token',\n 'apikey',\n 'api_key',\n 'api-key',\n 'auth',\n 'credential',\n 'private',\n];\n\nconst DEFAULT_MASK = '***';\n\nexport interface MaskSecretsOptions {\n patterns?: string[];\n mask?: string;\n deep?: boolean;\n}\n\nfunction isSecretKey(key: string, patterns: string[]): boolean {\n const lowerKey = key.toLowerCase();\n return patterns.some((pattern) => lowerKey.includes(pattern.toLowerCase()));\n}\n\nfunction maskUrlCredentials(url: string, mask: string): string {\n try {\n const parsed = new URL(url);\n if (parsed.password) {\n parsed.password = mask;\n }\n if (parsed.username && parsed.password) {\n parsed.username = mask;\n }\n return parsed.toString();\n } catch {\n return url;\n }\n}\n\nexport function maskSecrets(\n obj: unknown,\n options: MaskSecretsOptions = {},\n): unknown {\n const { patterns = DEFAULT_SECRET_PATTERNS, mask = DEFAULT_MASK, deep = true } = options;\n\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (typeof obj === 'string') {\n if (obj.startsWith('http://') || obj.startsWith('https://')) {\n return maskUrlCredentials(obj, mask);\n }\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return deep ? obj.map((item) => maskSecrets(item, options)) : obj;\n }\n\n if (typeof obj === 'object') {\n const result: Record<string | symbol, unknown> = {};\n\n // Copy Symbol properties first (important for Winston's internal symbols)\n for (const sym of Object.getOwnPropertySymbols(obj)) {\n result[sym] = (obj as Record<symbol, unknown>)[sym];\n }\n\n // Process string keys\n for (const [key, value] of Object.entries(obj)) {\n if (isSecretKey(key, patterns)) {\n result[key] = mask;\n } else if (deep && typeof value === 'object' && value !== null) {\n result[key] = maskSecrets(value, options);\n } else if (typeof value === 'string') {\n result[key] = maskSecrets(value, options);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n }\n\n return obj;\n}\n\nexport function createMasker(options: MaskSecretsOptions = {}) {\n return (obj: unknown): unknown => maskSecrets(obj, options);\n}\n","import { inspect } from 'util';\nimport { format, Logform } from 'winston';\nimport { LoggerStore } from './store.js';\nimport type { LoggerContext } from './types.js';\nimport { maskSecrets, type MaskSecretsOptions } from './utils/mask-secrets.js';\n\nconst DEFAULT_CONTEXT = 'APP';\n\nconst LEVEL_COLORS: Record<string, string> = {\n error: '\\x1b[31m', // red\n warn: '\\x1b[33m', // yellow\n info: '\\x1b[32m', // green\n http: '\\x1b[35m', // magenta\n verbose: '\\x1b[36m', // cyan\n debug: '\\x1b[34m', // blue\n silly: '\\x1b[90m', // grey\n};\nconst RESET = '\\x1b[0m';\n\nfunction colorizeLevel(level: string): string {\n const color = LEVEL_COLORS[level] || '';\n return color ? `${color}${level}${RESET}` : level;\n}\n\nfunction formatMeta(meta: Record<string, unknown>, colors: boolean): string {\n return Object.entries(meta)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => {\n if (typeof value === 'object') {\n const inspected = inspect(value, { depth: 4, colors, compact: false });\n return `\\n ${key}: ${inspected.split('\\n').join('\\n ')}`;\n }\n return `\\n ${key}: ${value}`;\n })\n .join('');\n}\n\nfunction addStoreContext<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format((info) => {\n const storeContext = store.getStore();\n if (storeContext) {\n return { ...info, ...storeContext };\n }\n return info;\n })();\n}\n\nfunction maskSecretsFormat(options?: MaskSecretsOptions): Logform.Format {\n return format((info) => {\n return maskSecrets(info, options) as Logform.TransformableInfo;\n })();\n}\n\nexport function createLocalFormat<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format.combine(\n format.errors({ stack: true }),\n format.timestamp(),\n addStoreContext(store),\n maskSecretsFormat(),\n format.printf(({ timestamp, level, context, message, ...meta }) => {\n const formattedMeta = formatMeta(meta, true);\n const coloredLevel = colorizeLevel(level);\n return `[${timestamp}] ${coloredLevel} [${context || DEFAULT_CONTEXT}] ${message}${formattedMeta}`;\n }),\n );\n}\n\nexport function createProductionFormat<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format.combine(\n format.errors({ stack: true }),\n format.timestamp(),\n addStoreContext(store),\n maskSecretsFormat(),\n format.json(),\n );\n}\n\nexport function createFormat<TContext extends LoggerContext>(isLocal: boolean, store: LoggerStore<TContext>): Logform.Format {\n return isLocal ? createLocalFormat(store) : createProductionFormat(store);\n}\n","import { transports } from 'winston';\nimport DailyRotateFile from 'winston-daily-rotate-file';\nimport type { LoggerConfig } from './types.js';\n\ntype Transport = transports.ConsoleTransportInstance | DailyRotateFile;\n\nexport function createTransports(config: LoggerConfig): Transport[] {\n const result: Transport[] = [new transports.Console()];\n\n if (config.file) {\n result.push(\n new DailyRotateFile({\n dirname: config.file.dirname,\n filename: config.file.filename,\n datePattern: config.file.datePattern ?? 'YYYY-MM-DD',\n zippedArchive: config.file.zippedArchive ?? false,\n maxSize: config.file.maxSize ?? '20m',\n maxFiles: config.file.maxFiles ?? '14d',\n }),\n );\n }\n\n return result;\n}\n\nexport function createExceptionHandlers(config: LoggerConfig): Transport[] {\n const result: Transport[] = [new transports.Console()];\n\n if (config.file) {\n result.push(\n new DailyRotateFile({\n dirname: config.file.dirname,\n filename: `exceptions-${config.file.filename}`,\n datePattern: config.file.datePattern ?? 'YYYY-MM-DD',\n zippedArchive: config.file.zippedArchive ?? false,\n maxSize: config.file.maxSize ?? '20m',\n maxFiles: config.file.maxFiles ?? '14d',\n }),\n );\n }\n\n return result;\n}\n","export const LOG_LEVELS = {\n error: 0,\n warn: 1,\n info: 2,\n http: 3,\n verbose: 4,\n debug: 5,\n silly: 6,\n} as const;\n\nexport type LogLevel = keyof typeof LOG_LEVELS;\n\nexport function isValidLogLevel(level: string): level is LogLevel {\n return level in LOG_LEVELS;\n}\n\nexport function assertLogLevel(level: string): asserts level is LogLevel {\n if (!isValidLogLevel(level)) {\n throw new Error(`Invalid log level: \"${level}\". Valid levels: ${Object.keys(LOG_LEVELS).join(', ')}`);\n }\n}\n\nexport interface FileConfig {\n dirname: string;\n filename: string;\n datePattern?: string;\n zippedArchive?: boolean;\n maxSize?: string;\n maxFiles?: string;\n}\n\nexport interface LoggerConfig {\n level: LogLevel;\n file?: FileConfig;\n}\n\nexport type LoggerContext = Record<string, unknown>;\n\nexport interface LevelOverride<TContext extends LoggerContext> {\n match: Partial<TContext>;\n level: LogLevel;\n}\n","import { createLogger, type Logger as WinstonLogger } from 'winston';\nimport { LoggerStore } from './store.js';\nimport { createFormat } from './formatters.js';\nimport { createTransports, createExceptionHandlers } from './transports.js';\nimport {\n LOG_LEVELS,\n assertLogLevel,\n type LoggerConfig,\n type LoggerContext,\n type LevelOverride,\n type LogLevel,\n} from './types.js';\n\nexport interface LoggerState<TContext extends LoggerContext> {\n winston: WinstonLogger;\n store: LoggerStore<TContext>;\n defaultLevel: LogLevel;\n levelOverrides: Map<string, LevelOverride<TContext>>;\n}\n\nexport function createState<TContext extends LoggerContext>(\n config: LoggerConfig,\n store?: LoggerStore<TContext>,\n): LoggerState<TContext> {\n assertLogLevel(config.level);\n\n const loggerStore = store ?? new LoggerStore<TContext>();\n const isLocal = process.env.NODE_ENV !== 'production';\n const exceptionHandlers = createExceptionHandlers(config);\n\n const winston = createLogger({\n level: 'silly', // Accept all, we filter in shouldLog()\n format: createFormat(isLocal, loggerStore),\n transports: createTransports(config),\n exceptionHandlers,\n rejectionHandlers: exceptionHandlers,\n exitOnError: false,\n });\n\n return {\n winston,\n store: loggerStore,\n defaultLevel: config.level,\n levelOverrides: new Map(),\n };\n}\n\nexport function shouldLog<TContext extends LoggerContext>(\n state: LoggerState<TContext>,\n level: LogLevel,\n): boolean {\n const effectiveLevel = getEffectiveLevel(state);\n return LOG_LEVELS[level] <= LOG_LEVELS[effectiveLevel];\n}\n\nfunction getEffectiveLevel<TContext extends LoggerContext>(\n state: LoggerState<TContext>,\n): LogLevel {\n const context = state.store.getStore();\n if (!context) return state.defaultLevel;\n\n for (const { match, level } of state.levelOverrides.values()) {\n if (matchesContext(context, match)) {\n return level;\n }\n }\n return state.defaultLevel;\n}\n\nfunction matchesContext<TContext extends LoggerContext>(\n context: TContext,\n match: Partial<TContext>,\n): boolean {\n return Object.entries(match).every(([key, value]) => context[key] === value);\n}\n","import { LoggerStore } from './store.js';\nimport { createState, shouldLog, type LoggerState } from './state.js';\nimport { assertLogLevel, type LoggerConfig, type LoggerContext, type LevelOverride, type LogLevel } from './types.js';\n\nexport class Logger<TContext extends LoggerContext = LoggerContext> {\n private constructor(\n private state: LoggerState<TContext>,\n private context: string,\n ) {}\n\n static create<TContext extends LoggerContext = LoggerContext>(\n config: LoggerConfig,\n store?: LoggerStore<TContext>,\n ): Logger<TContext> {\n const state = createState(config, store);\n return new Logger(state, 'APP');\n }\n\n child(context: string): Logger<TContext> {\n return new Logger(this.state, context);\n }\n\n // State accessors\n\n getStore(): LoggerStore<TContext> {\n return this.state.store;\n }\n\n setLevelOverride(match: Partial<TContext>, level: LogLevel): void {\n assertLogLevel(level);\n const key = JSON.stringify(match);\n this.state.levelOverrides.set(key, { match, level });\n }\n\n removeLevelOverride(match: Partial<TContext>): void {\n const key = JSON.stringify(match);\n this.state.levelOverrides.delete(key);\n }\n\n clearLevelOverrides(): void {\n this.state.levelOverrides.clear();\n }\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return Array.from(this.state.levelOverrides.values());\n }\n\n // Profiling\n\n profile(id: string, meta?: object): void {\n this.state.winston.profile(id, meta);\n }\n\n // Logging methods\n\n error(message: string, error?: Error | unknown, meta?: object): void {\n if (!shouldLog(this.state, 'error')) return;\n this.log('error', message, meta, error);\n }\n\n warn(message: string, meta?: object): void {\n if (!shouldLog(this.state, 'warn')) return;\n this.log('warn', message, meta);\n }\n\n info(message: string, meta?: object): void {\n if (!shouldLog(this.state, 'info')) return;\n this.log('info', message, meta);\n }\n\n http(message: string, meta?: object): void {\n if (!shouldLog(this.state, 'http')) return;\n this.log('http', message, meta);\n }\n\n verbose(message: string, meta?: object): void {\n if (!shouldLog(this.state, 'verbose')) return;\n this.log('verbose', message, meta);\n }\n\n debug(message: string, meta?: object): void {\n if (!shouldLog(this.state, 'debug')) return;\n this.log('debug', message, meta);\n }\n\n silly(message: string, meta?: object): void {\n if (!shouldLog(this.state, 'silly')) return;\n this.log('silly', message, meta);\n }\n\n // Private\n\n private log(level: LogLevel, message: string, meta?: object, error?: Error | unknown): void {\n const logMeta: Record<string, unknown> = { context: this.context, ...meta };\n\n if (error instanceof Error) {\n logMeta.errorMessage = error.message;\n logMeta.stack = error.stack;\n } else if (error !== undefined) {\n logMeta.error = error;\n }\n\n this.state.winston.log(level, message, logMeta);\n }\n}\n","import { Logger } from './logger.js';\nimport { LoggerStore } from './store.js';\nimport type { LoggerConfig, LoggerContext, LevelOverride, LogLevel } from './types.js';\n\nexport interface SingletonLogger<TContext extends LoggerContext> {\n init(config: LoggerConfig, store?: LoggerStore<TContext>): Logger<TContext>;\n get(): Logger<TContext>;\n child(context: string): Logger<TContext>;\n getStore(): LoggerStore<TContext>;\n setLevelOverride(match: Partial<TContext>, level: LogLevel): void;\n removeLevelOverride(match: Partial<TContext>): void;\n getLevelOverrides(): LevelOverride<TContext>[];\n clearLevelOverrides(): void;\n}\n\nexport function createSingletonLogger<\n TContext extends LoggerContext = LoggerContext,\n>(): SingletonLogger<TContext> {\n let root: Logger<TContext> | null = null;\n\n const ensureInit = (): Logger<TContext> => {\n if (!root) {\n throw new Error('Logger not initialized. Call init(config) first.');\n }\n return root;\n };\n\n return {\n init(config: LoggerConfig, store?: LoggerStore<TContext>): Logger<TContext> {\n if (!root) {\n root = Logger.create(config, store);\n }\n return root;\n },\n\n get(): Logger<TContext> {\n return ensureInit();\n },\n\n child(context: string): Logger<TContext> {\n return ensureInit().child(context);\n },\n\n getStore(): LoggerStore<TContext> {\n return ensureInit().getStore();\n },\n\n setLevelOverride(match: Partial<TContext>, level: LogLevel): void {\n ensureInit().setLevelOverride(match, level);\n },\n\n removeLevelOverride(match: Partial<TContext>): void {\n ensureInit().removeLevelOverride(match);\n },\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return ensureInit().getLevelOverrides();\n },\n\n clearLevelOverrides(): void {\n ensureInit().clearLevelOverrides();\n },\n };\n}\n","export interface TimingResult {\n label: string;\n durationMs: number;\n durationFormatted: string;\n}\n\nexport interface Timer {\n end: () => TimingResult;\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms.toFixed(2)}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(1);\n return `${minutes}m ${seconds}s`;\n}\n\nexport function createTimer(label: string): Timer {\n const start = performance.now();\n\n return {\n end(): TimingResult {\n const durationMs = performance.now() - start;\n return {\n label,\n durationMs,\n durationFormatted: formatDuration(durationMs),\n };\n },\n };\n}\n\nexport async function measureAsync<T>(\n label: string,\n fn: () => Promise<T>,\n): Promise<{ result: T; timing: TimingResult }> {\n const timer = createTimer(label);\n const result = await fn();\n const timing = timer.end();\n return { result, timing };\n}\n\nexport function measureSync<T>(\n label: string,\n fn: () => T,\n): { result: T; timing: TimingResult } {\n const timer = createTimer(label);\n const result = fn();\n const timing = timer.end();\n return { result, timing };\n}\n","import { randomUUID } from 'crypto';\n\nexport interface RequestIdOptions {\n prefix?: string;\n short?: boolean;\n}\n\nexport function generateRequestId(options: RequestIdOptions = {}): string {\n const { prefix, short = false } = options;\n const uuid = randomUUID();\n const id = short ? uuid.split('-')[0] : uuid;\n return prefix ? `${prefix}-${id}` : id;\n}\n\nexport function extractRequestId(headers: Record<string, string | string[] | undefined>): string | undefined {\n const headerNames = ['x-request-id', 'x-correlation-id', 'x-trace-id'];\n\n for (const name of headerNames) {\n const value = headers[name];\n if (typeof value === 'string' && value.length > 0) {\n return value;\n }\n if (Array.isArray(value) && value.length > 0) {\n return value[0];\n }\n }\n\n return undefined;\n}\n\nexport function getOrGenerateRequestId(\n headers: Record<string, string | string[] | undefined>,\n options: RequestIdOptions = {},\n): string {\n return extractRequestId(headers) ?? generateRequestId(options);\n}\n"]}
package/dist/index.mjs CHANGED
@@ -1,10 +1,19 @@
1
1
  import { createLogger, transports, format } from 'winston';
2
+ import { AsyncLocalStorage } from 'async_hooks';
2
3
  import { inspect } from 'util';
3
4
  import DailyRotateFile from 'winston-daily-rotate-file';
4
- import { AsyncLocalStorage } from 'async_hooks';
5
5
  import { randomUUID } from 'crypto';
6
6
 
7
- // src/logger.ts
7
+ // src/state.ts
8
+ var LoggerStore = class {
9
+ storage = new AsyncLocalStorage();
10
+ getStore() {
11
+ return this.storage.getStore();
12
+ }
13
+ run(context, fn) {
14
+ return this.storage.run(context, fn);
15
+ }
16
+ };
8
17
 
9
18
  // src/utils/mask-secrets.ts
10
19
  var DEFAULT_SECRET_PATTERNS = [
@@ -53,6 +62,9 @@ function maskSecrets(obj, options = {}) {
53
62
  }
54
63
  if (typeof obj === "object") {
55
64
  const result = {};
65
+ for (const sym of Object.getOwnPropertySymbols(obj)) {
66
+ result[sym] = obj[sym];
67
+ }
56
68
  for (const [key, value] of Object.entries(obj)) {
57
69
  if (isSecretKey(key, patterns)) {
58
70
  result[key] = mask;
@@ -146,21 +158,16 @@ function createFormat(isLocal, store) {
146
158
  return isLocal ? createLocalFormat(store) : createProductionFormat(store);
147
159
  }
148
160
  function createTransports(config) {
149
- const result = [
150
- new transports.Console({
151
- level: config.console.level
152
- })
153
- ];
161
+ const result = [new transports.Console()];
154
162
  if (config.file) {
155
163
  result.push(
156
164
  new DailyRotateFile({
157
165
  dirname: config.file.dirname,
158
166
  filename: config.file.filename,
159
- level: config.file.level,
160
- datePattern: config.file.datePattern,
161
- zippedArchive: config.file.zippedArchive,
162
- maxSize: config.file.maxSize,
163
- maxFiles: config.file.maxFiles
167
+ datePattern: config.file.datePattern ?? "YYYY-MM-DD",
168
+ zippedArchive: config.file.zippedArchive ?? false,
169
+ maxSize: config.file.maxSize ?? "20m",
170
+ maxFiles: config.file.maxFiles ?? "14d"
164
171
  })
165
172
  );
166
173
  }
@@ -172,28 +179,18 @@ function createExceptionHandlers(config) {
172
179
  result.push(
173
180
  new DailyRotateFile({
174
181
  dirname: config.file.dirname,
175
- filename: config.file.filename,
176
- datePattern: config.file.datePattern,
177
- zippedArchive: config.file.zippedArchive,
178
- maxSize: config.file.maxSize,
179
- maxFiles: config.file.maxFiles
182
+ filename: `exceptions-${config.file.filename}`,
183
+ datePattern: config.file.datePattern ?? "YYYY-MM-DD",
184
+ zippedArchive: config.file.zippedArchive ?? false,
185
+ maxSize: config.file.maxSize ?? "20m",
186
+ maxFiles: config.file.maxFiles ?? "14d"
180
187
  })
181
188
  );
182
189
  }
183
190
  return result;
184
191
  }
185
- var LoggerStore = class {
186
- storage = new AsyncLocalStorage();
187
- getStore() {
188
- return this.storage.getStore();
189
- }
190
- run(context, fn) {
191
- return this.storage.run(context, fn);
192
- }
193
- };
194
192
 
195
- // src/logger.ts
196
- var DEFAULT_CONTEXT2 = "APP";
193
+ // src/types.ts
197
194
  var LOG_LEVELS = {
198
195
  error: 0,
199
196
  warn: 1,
@@ -203,135 +200,169 @@ var LOG_LEVELS = {
203
200
  debug: 5,
204
201
  silly: 6
205
202
  };
206
- var BaseLogger = class {
207
- winstonLogger;
208
- defaultLevel;
209
- store;
210
- levelOverrides = /* @__PURE__ */ new Map();
211
- constructor(config, store) {
212
- const isLocal = process.env.NODE_ENV !== "production";
213
- this.defaultLevel = config.level;
214
- this.store = store ?? new LoggerStore();
215
- const exceptionHandlers = createExceptionHandlers(config);
216
- this.winstonLogger = createLogger({
217
- level: "silly",
218
- // Allow all, we filter manually
219
- format: createFormat(isLocal, this.store),
220
- transports: createTransports(config),
221
- exceptionHandlers,
222
- rejectionHandlers: exceptionHandlers,
223
- exitOnError: false
224
- });
203
+ function isValidLogLevel(level) {
204
+ return level in LOG_LEVELS;
205
+ }
206
+ function assertLogLevel(level) {
207
+ if (!isValidLogLevel(level)) {
208
+ throw new Error(`Invalid log level: "${level}". Valid levels: ${Object.keys(LOG_LEVELS).join(", ")}`);
225
209
  }
210
+ }
211
+
212
+ // src/state.ts
213
+ function createState(config, store) {
214
+ assertLogLevel(config.level);
215
+ const loggerStore = store ?? new LoggerStore();
216
+ const isLocal = process.env.NODE_ENV !== "production";
217
+ const exceptionHandlers = createExceptionHandlers(config);
218
+ const winston = createLogger({
219
+ level: "silly",
220
+ // Accept all, we filter in shouldLog()
221
+ format: createFormat(isLocal, loggerStore),
222
+ transports: createTransports(config),
223
+ exceptionHandlers,
224
+ rejectionHandlers: exceptionHandlers,
225
+ exitOnError: false
226
+ });
227
+ return {
228
+ winston,
229
+ store: loggerStore,
230
+ defaultLevel: config.level,
231
+ levelOverrides: /* @__PURE__ */ new Map()
232
+ };
233
+ }
234
+ function shouldLog(state, level) {
235
+ const effectiveLevel = getEffectiveLevel(state);
236
+ return LOG_LEVELS[level] <= LOG_LEVELS[effectiveLevel];
237
+ }
238
+ function getEffectiveLevel(state) {
239
+ const context = state.store.getStore();
240
+ if (!context) return state.defaultLevel;
241
+ for (const { match, level } of state.levelOverrides.values()) {
242
+ if (matchesContext(context, match)) {
243
+ return level;
244
+ }
245
+ }
246
+ return state.defaultLevel;
247
+ }
248
+ function matchesContext(context, match) {
249
+ return Object.entries(match).every(([key, value]) => context[key] === value);
250
+ }
251
+
252
+ // src/logger.ts
253
+ var Logger = class _Logger {
254
+ constructor(state, context) {
255
+ this.state = state;
256
+ this.context = context;
257
+ }
258
+ static create(config, store) {
259
+ const state = createState(config, store);
260
+ return new _Logger(state, "APP");
261
+ }
262
+ child(context) {
263
+ return new _Logger(this.state, context);
264
+ }
265
+ // State accessors
226
266
  getStore() {
227
- return this.store;
267
+ return this.state.store;
228
268
  }
229
269
  setLevelOverride(match, level) {
270
+ assertLogLevel(level);
230
271
  const key = JSON.stringify(match);
231
- this.levelOverrides.set(key, { match, level });
272
+ this.state.levelOverrides.set(key, { match, level });
232
273
  }
233
274
  removeLevelOverride(match) {
234
275
  const key = JSON.stringify(match);
235
- this.levelOverrides.delete(key);
276
+ this.state.levelOverrides.delete(key);
236
277
  }
237
278
  clearLevelOverrides() {
238
- this.levelOverrides.clear();
279
+ this.state.levelOverrides.clear();
239
280
  }
240
281
  getLevelOverrides() {
241
- return Array.from(this.levelOverrides.values());
282
+ return Array.from(this.state.levelOverrides.values());
242
283
  }
243
- getEffectiveLevel() {
244
- const context = this.store.getStore();
245
- if (!context) return this.defaultLevel;
246
- for (const { match, level } of this.levelOverrides.values()) {
247
- if (this.matchesContext(context, match)) {
248
- return level;
249
- }
250
- }
251
- return this.defaultLevel;
284
+ // Profiling
285
+ profile(id, meta) {
286
+ this.state.winston.profile(id, meta);
252
287
  }
253
- matchesContext(context, match) {
254
- return Object.entries(match).every(([key, value]) => context[key] === value);
288
+ // Logging methods
289
+ error(message, error, meta) {
290
+ if (!shouldLog(this.state, "error")) return;
291
+ this.log("error", message, meta, error);
255
292
  }
256
- shouldLog(level) {
257
- const effectiveLevel = this.getEffectiveLevel();
258
- return LOG_LEVELS[level] <= LOG_LEVELS[effectiveLevel];
293
+ warn(message, meta) {
294
+ if (!shouldLog(this.state, "warn")) return;
295
+ this.log("warn", message, meta);
259
296
  }
260
- getChildLogger(context) {
261
- return this.winstonLogger.child({ context });
297
+ info(message, meta) {
298
+ if (!shouldLog(this.state, "info")) return;
299
+ this.log("info", message, meta);
262
300
  }
263
- profile(id, meta) {
264
- this.winstonLogger.profile(id, meta);
301
+ http(message, meta) {
302
+ if (!shouldLog(this.state, "http")) return;
303
+ this.log("http", message, meta);
265
304
  }
266
- log(message, context, meta) {
267
- if (!this.shouldLog("info")) return;
268
- this.winstonLogger.info(message, { context: context || DEFAULT_CONTEXT2, ...meta });
269
- }
270
- error(message, error, context) {
271
- if (!this.shouldLog("error")) return;
272
- const meta = { context: context || DEFAULT_CONTEXT2 };
273
- if (error instanceof Error) {
274
- meta.errorMessage = error.message;
275
- meta.errorStack = error.stack;
276
- } else if (error) {
277
- meta.error = error;
278
- }
279
- this.winstonLogger.error(message, meta);
305
+ verbose(message, meta) {
306
+ if (!shouldLog(this.state, "verbose")) return;
307
+ this.log("verbose", message, meta);
280
308
  }
281
- warn(message, context, meta) {
282
- if (!this.shouldLog("warn")) return;
283
- this.winstonLogger.warn(message, { context: context || DEFAULT_CONTEXT2, ...meta });
309
+ debug(message, meta) {
310
+ if (!shouldLog(this.state, "debug")) return;
311
+ this.log("debug", message, meta);
284
312
  }
285
- debug(message, context, meta) {
286
- if (!this.shouldLog("debug")) return;
287
- this.winstonLogger.debug(message, { context: context || DEFAULT_CONTEXT2, ...meta });
313
+ silly(message, meta) {
314
+ if (!shouldLog(this.state, "silly")) return;
315
+ this.log("silly", message, meta);
288
316
  }
289
- info(message, context, meta) {
290
- if (!this.shouldLog("info")) return;
291
- this.winstonLogger.info(message, { context: context || DEFAULT_CONTEXT2, ...meta });
292
- }
293
- verbose(message, context, meta) {
294
- if (!this.shouldLog("verbose")) return;
295
- this.winstonLogger.verbose(message, { context: context || DEFAULT_CONTEXT2, ...meta });
317
+ // Private
318
+ log(level, message, meta, error) {
319
+ const logMeta = { context: this.context, ...meta };
320
+ if (error instanceof Error) {
321
+ logMeta.errorMessage = error.message;
322
+ logMeta.stack = error.stack;
323
+ } else if (error !== void 0) {
324
+ logMeta.error = error;
325
+ }
326
+ this.state.winston.log(level, message, logMeta);
296
327
  }
297
328
  };
298
329
 
299
330
  // src/singleton.ts
300
331
  function createSingletonLogger() {
301
- let instance = null;
302
- const ensureInstance = () => {
303
- if (!instance) {
304
- throw new Error("Logger not initialized. Call getInstance(config) first.");
332
+ let root = null;
333
+ const ensureInit = () => {
334
+ if (!root) {
335
+ throw new Error("Logger not initialized. Call init(config) first.");
305
336
  }
306
- return instance;
337
+ return root;
307
338
  };
308
339
  return {
309
- getInstance(config) {
310
- if (!instance) {
311
- if (!config) {
312
- throw new Error("Logger config is required for first initialization");
313
- }
314
- instance = new BaseLogger(config);
340
+ init(config, store) {
341
+ if (!root) {
342
+ root = Logger.create(config, store);
315
343
  }
316
- return instance;
344
+ return root;
317
345
  },
318
- getStore() {
319
- return ensureInstance().getStore();
346
+ get() {
347
+ return ensureInit();
348
+ },
349
+ child(context) {
350
+ return ensureInit().child(context);
320
351
  },
321
- for(context) {
322
- return ensureInstance().getChildLogger(context);
352
+ getStore() {
353
+ return ensureInit().getStore();
323
354
  },
324
355
  setLevelOverride(match, level) {
325
- ensureInstance().setLevelOverride(match, level);
356
+ ensureInit().setLevelOverride(match, level);
326
357
  },
327
358
  removeLevelOverride(match) {
328
- ensureInstance().removeLevelOverride(match);
359
+ ensureInit().removeLevelOverride(match);
329
360
  },
330
361
  getLevelOverrides() {
331
- return ensureInstance().getLevelOverrides();
362
+ return ensureInit().getLevelOverrides();
332
363
  },
333
364
  clearLevelOverrides() {
334
- ensureInstance().clearLevelOverrides();
365
+ ensureInit().clearLevelOverrides();
335
366
  }
336
367
  };
337
368
  }
@@ -396,6 +427,6 @@ function getOrGenerateRequestId(headers, options = {}) {
396
427
  return extractRequestId(headers) ?? generateRequestId(options);
397
428
  }
398
429
 
399
- export { BaseLogger, LoggerStore, createMasker, createSingletonLogger, extractRequestId, generateRequestId, getOrGenerateRequestId, maskSecrets, measureAsync, measureSync };
430
+ export { LOG_LEVELS, Logger, LoggerStore, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, measureAsync, measureSync };
400
431
  //# sourceMappingURL=index.mjs.map
401
432
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/mask-secrets.ts","../src/formatters.ts","../src/transports.ts","../src/store.ts","../src/logger.ts","../src/singleton.ts","../src/utils/timing.ts","../src/utils/request-id.ts"],"names":["DEFAULT_CONTEXT"],"mappings":"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","file":"index.mjs","sourcesContent":["const DEFAULT_SECRET_PATTERNS = [\n 'password',\n 'secret',\n 'token',\n 'apikey',\n 'api_key',\n 'api-key',\n 'auth',\n 'credential',\n 'private',\n];\n\nconst DEFAULT_MASK = '***';\n\nexport interface MaskSecretsOptions {\n patterns?: string[];\n mask?: string;\n deep?: boolean;\n}\n\nfunction isSecretKey(key: string, patterns: string[]): boolean {\n const lowerKey = key.toLowerCase();\n return patterns.some((pattern) => lowerKey.includes(pattern.toLowerCase()));\n}\n\nfunction maskUrlCredentials(url: string, mask: string): string {\n try {\n const parsed = new URL(url);\n if (parsed.password) {\n parsed.password = mask;\n }\n if (parsed.username && parsed.password) {\n parsed.username = mask;\n }\n return parsed.toString();\n } catch {\n return url;\n }\n}\n\nexport function maskSecrets(\n obj: unknown,\n options: MaskSecretsOptions = {},\n): unknown {\n const { patterns = DEFAULT_SECRET_PATTERNS, mask = DEFAULT_MASK, deep = true } = options;\n\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (typeof obj === 'string') {\n if (obj.startsWith('http://') || obj.startsWith('https://')) {\n return maskUrlCredentials(obj, mask);\n }\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return deep ? obj.map((item) => maskSecrets(item, options)) : obj;\n }\n\n if (typeof obj === 'object') {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n if (isSecretKey(key, patterns)) {\n result[key] = mask;\n } else if (deep && typeof value === 'object' && value !== null) {\n result[key] = maskSecrets(value, options);\n } else if (typeof value === 'string') {\n result[key] = maskSecrets(value, options);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n }\n\n return obj;\n}\n\nexport function createMasker(options: MaskSecretsOptions = {}) {\n return (obj: unknown): unknown => maskSecrets(obj, options);\n}\n","import { inspect } from 'util';\nimport { format, Logform } from 'winston';\nimport { LoggerStore } from './store.js';\nimport type { LoggerContext } from './types.js';\nimport { maskSecrets, type MaskSecretsOptions } from './utils/mask-secrets.js';\n\nconst DEFAULT_CONTEXT = 'APP';\n\nconst LEVEL_COLORS: Record<string, string> = {\n error: '\\x1b[31m', // red\n warn: '\\x1b[33m', // yellow\n info: '\\x1b[32m', // green\n http: '\\x1b[35m', // magenta\n verbose: '\\x1b[36m', // cyan\n debug: '\\x1b[34m', // blue\n silly: '\\x1b[90m', // grey\n};\nconst RESET = '\\x1b[0m';\n\nfunction colorizeLevel(level: string): string {\n const color = LEVEL_COLORS[level] || '';\n return color ? `${color}${level}${RESET}` : level;\n}\n\nfunction formatMeta(meta: Record<string, unknown>, colors: boolean): string {\n return Object.entries(meta)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => {\n if (typeof value === 'object') {\n const inspected = inspect(value, { depth: 4, colors, compact: false });\n return `\\n ${key}: ${inspected.split('\\n').join('\\n ')}`;\n }\n return `\\n ${key}: ${value}`;\n })\n .join('');\n}\n\nfunction addStoreContext<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format((info) => {\n const storeContext = store.getStore();\n if (storeContext) {\n return { ...info, ...storeContext };\n }\n return info;\n })();\n}\n\nfunction maskSecretsFormat(options?: MaskSecretsOptions): Logform.Format {\n return format((info) => {\n return maskSecrets(info, options) as Logform.TransformableInfo;\n })();\n}\n\nexport function createLocalFormat<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format.combine(\n format.errors({ stack: true }),\n format.timestamp(),\n addStoreContext(store),\n maskSecretsFormat(),\n format.printf(({ timestamp, level, context, message, ...meta }) => {\n const formattedMeta = formatMeta(meta, true);\n const coloredLevel = colorizeLevel(level);\n return `[${timestamp}] ${coloredLevel} [${context || DEFAULT_CONTEXT}] ${message}${formattedMeta}`;\n }),\n );\n}\n\nexport function createProductionFormat<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format.combine(\n format.errors({ stack: true }),\n format.timestamp(),\n addStoreContext(store),\n maskSecretsFormat(),\n format.json(),\n );\n}\n\nexport function createFormat<TContext extends LoggerContext>(isLocal: boolean, store: LoggerStore<TContext>): Logform.Format {\n return isLocal ? createLocalFormat(store) : createProductionFormat(store);\n}\n","import { transports } from 'winston';\nimport DailyRotateFile from 'winston-daily-rotate-file';\nimport { LoggerConfig } from './types.js';\n\ntype Transport = transports.ConsoleTransportInstance | DailyRotateFile;\n\nexport function createTransports(config: LoggerConfig): Transport[] {\n const result: Transport[] = [\n new transports.Console({\n level: config.console.level,\n }),\n ];\n\n if (config.file) {\n result.push(\n new DailyRotateFile({\n dirname: config.file.dirname,\n filename: config.file.filename,\n level: config.file.level,\n datePattern: config.file.datePattern,\n zippedArchive: config.file.zippedArchive,\n maxSize: config.file.maxSize,\n maxFiles: config.file.maxFiles,\n }),\n );\n }\n\n return result;\n}\n\nexport function createExceptionHandlers(config: LoggerConfig): Transport[] {\n const result: Transport[] = [new transports.Console()];\n\n if (config.file) {\n result.push(\n new DailyRotateFile({\n dirname: config.file.dirname,\n filename: config.file.filename,\n datePattern: config.file.datePattern,\n zippedArchive: config.file.zippedArchive,\n maxSize: config.file.maxSize,\n maxFiles: config.file.maxFiles,\n }),\n );\n }\n\n return result;\n}\n","import { AsyncLocalStorage } from 'async_hooks';\nimport type { LoggerContext } from './types.js';\n\nexport class LoggerStore<TContext extends LoggerContext = LoggerContext> {\n private storage = new AsyncLocalStorage<TContext>();\n\n getStore(): TContext | undefined {\n return this.storage.getStore();\n }\n\n run<T>(context: TContext, fn: () => T): T {\n return this.storage.run(context, fn);\n }\n}\n","import { createLogger, Logger } from 'winston';\nimport type { LoggerConfig, LoggerContext, LevelOverride } from './types.js';\nimport { createFormat } from './formatters.js';\nimport { createTransports, createExceptionHandlers } from './transports.js';\nimport { LoggerStore } from './store.js';\n\nconst DEFAULT_CONTEXT = 'APP';\n\nconst LOG_LEVELS: Record<string, number> = {\n error: 0,\n warn: 1,\n info: 2,\n http: 3,\n verbose: 4,\n debug: 5,\n silly: 6,\n};\n\nexport class BaseLogger<TContext extends LoggerContext = LoggerContext> {\n private winstonLogger: Logger;\n private defaultLevel: string;\n private store: LoggerStore<TContext>;\n private levelOverrides: Map<string, LevelOverride<TContext>> = new Map();\n\n constructor(config: LoggerConfig, store?: LoggerStore<TContext>) {\n const isLocal = process.env.NODE_ENV !== 'production';\n\n this.defaultLevel = config.level;\n this.store = store ?? new LoggerStore<TContext>();\n\n const exceptionHandlers = createExceptionHandlers(config);\n\n this.winstonLogger = createLogger({\n level: 'silly', // Allow all, we filter manually\n format: createFormat(isLocal, this.store),\n transports: createTransports(config),\n exceptionHandlers,\n rejectionHandlers: exceptionHandlers,\n exitOnError: false,\n });\n }\n\n getStore(): LoggerStore<TContext> {\n return this.store;\n }\n\n setLevelOverride(match: Partial<TContext>, level: string): void {\n const key = JSON.stringify(match);\n this.levelOverrides.set(key, { match, level });\n }\n\n removeLevelOverride(match: Partial<TContext>): void {\n const key = JSON.stringify(match);\n this.levelOverrides.delete(key);\n }\n\n clearLevelOverrides(): void {\n this.levelOverrides.clear();\n }\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return Array.from(this.levelOverrides.values());\n }\n\n private getEffectiveLevel(): string {\n const context = this.store.getStore();\n if (!context) return this.defaultLevel;\n\n for (const { match, level } of this.levelOverrides.values()) {\n if (this.matchesContext(context, match)) {\n return level;\n }\n }\n return this.defaultLevel;\n }\n\n private matchesContext(context: TContext, match: Partial<TContext>): boolean {\n return Object.entries(match).every(([key, value]) => context[key] === value);\n }\n\n private shouldLog(level: string): boolean {\n const effectiveLevel = this.getEffectiveLevel();\n return LOG_LEVELS[level] <= LOG_LEVELS[effectiveLevel];\n }\n\n getChildLogger(context: string): Logger {\n return this.winstonLogger.child({ context });\n }\n\n profile(id: string, meta?: object): void {\n this.winstonLogger.profile(id, meta);\n }\n\n log(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('info')) return;\n this.winstonLogger.info(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n\n error(message: string, error?: Error | unknown, context?: string): void {\n if (!this.shouldLog('error')) return;\n const meta: Record<string, unknown> = { context: context || DEFAULT_CONTEXT };\n if (error instanceof Error) {\n meta.errorMessage = error.message;\n meta.errorStack = error.stack;\n } else if (error) {\n meta.error = error;\n }\n this.winstonLogger.error(message, meta);\n }\n\n warn(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('warn')) return;\n this.winstonLogger.warn(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n\n debug(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('debug')) return;\n this.winstonLogger.debug(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n\n info(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('info')) return;\n this.winstonLogger.info(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n\n verbose(message: string, context?: string, meta?: object): void {\n if (!this.shouldLog('verbose')) return;\n this.winstonLogger.verbose(message, { context: context || DEFAULT_CONTEXT, ...meta });\n }\n}\n","import { Logger } from 'winston';\nimport { BaseLogger } from './logger.js';\nimport { LoggerStore } from './store.js';\nimport type { LoggerConfig, LoggerContext, LevelOverride } from './types.js';\n\nexport interface SingletonLogger<TContext extends LoggerContext> {\n getInstance(config?: LoggerConfig): BaseLogger<TContext>;\n getStore(): LoggerStore<TContext>;\n for(context: string): Logger;\n setLevelOverride(match: Partial<TContext>, level: string): void;\n removeLevelOverride(match: Partial<TContext>): void;\n getLevelOverrides(): LevelOverride<TContext>[];\n clearLevelOverrides(): void;\n}\n\nexport function createSingletonLogger<TContext extends LoggerContext>(): SingletonLogger<TContext> {\n let instance: BaseLogger<TContext> | null = null;\n\n const ensureInstance = (): BaseLogger<TContext> => {\n if (!instance) {\n throw new Error('Logger not initialized. Call getInstance(config) first.');\n }\n return instance;\n };\n\n return {\n getInstance(config?: LoggerConfig): BaseLogger<TContext> {\n if (!instance) {\n if (!config) {\n throw new Error('Logger config is required for first initialization');\n }\n instance = new BaseLogger<TContext>(config);\n }\n return instance;\n },\n\n getStore(): LoggerStore<TContext> {\n return ensureInstance().getStore();\n },\n\n for(context: string): Logger {\n return ensureInstance().getChildLogger(context);\n },\n\n setLevelOverride(match: Partial<TContext>, level: string): void {\n ensureInstance().setLevelOverride(match, level);\n },\n\n removeLevelOverride(match: Partial<TContext>): void {\n ensureInstance().removeLevelOverride(match);\n },\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return ensureInstance().getLevelOverrides();\n },\n\n clearLevelOverrides(): void {\n ensureInstance().clearLevelOverrides();\n },\n };\n}\n","export interface TimingResult {\n label: string;\n durationMs: number;\n durationFormatted: string;\n}\n\nexport interface Timer {\n end: () => TimingResult;\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms.toFixed(2)}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(1);\n return `${minutes}m ${seconds}s`;\n}\n\nexport function createTimer(label: string): Timer {\n const start = performance.now();\n\n return {\n end(): TimingResult {\n const durationMs = performance.now() - start;\n return {\n label,\n durationMs,\n durationFormatted: formatDuration(durationMs),\n };\n },\n };\n}\n\nexport async function measureAsync<T>(\n label: string,\n fn: () => Promise<T>,\n): Promise<{ result: T; timing: TimingResult }> {\n const timer = createTimer(label);\n const result = await fn();\n const timing = timer.end();\n return { result, timing };\n}\n\nexport function measureSync<T>(\n label: string,\n fn: () => T,\n): { result: T; timing: TimingResult } {\n const timer = createTimer(label);\n const result = fn();\n const timing = timer.end();\n return { result, timing };\n}\n","import { randomUUID } from 'crypto';\n\nexport interface RequestIdOptions {\n prefix?: string;\n short?: boolean;\n}\n\nexport function generateRequestId(options: RequestIdOptions = {}): string {\n const { prefix, short = false } = options;\n const uuid = randomUUID();\n const id = short ? uuid.split('-')[0] : uuid;\n return prefix ? `${prefix}-${id}` : id;\n}\n\nexport function extractRequestId(headers: Record<string, string | string[] | undefined>): string | undefined {\n const headerNames = ['x-request-id', 'x-correlation-id', 'x-trace-id'];\n\n for (const name of headerNames) {\n const value = headers[name];\n if (typeof value === 'string' && value.length > 0) {\n return value;\n }\n if (Array.isArray(value) && value.length > 0) {\n return value[0];\n }\n }\n\n return undefined;\n}\n\nexport function getOrGenerateRequestId(\n headers: Record<string, string | string[] | undefined>,\n options: RequestIdOptions = {},\n): string {\n return extractRequestId(headers) ?? generateRequestId(options);\n}\n"]}
1
+ {"version":3,"sources":["../src/store.ts","../src/utils/mask-secrets.ts","../src/formatters.ts","../src/transports.ts","../src/types.ts","../src/state.ts","../src/logger.ts","../src/singleton.ts","../src/utils/timing.ts","../src/utils/request-id.ts"],"names":[],"mappings":";;;;;;;AAGO,IAAM,cAAN,MAAkE;AAAA,EAC/D,OAAA,GAAU,IAAI,iBAAA,EAA4B;AAAA,EAElD,QAAA,GAAiC;AAC/B,IAAA,OAAO,IAAA,CAAK,QAAQ,QAAA,EAAS;AAAA,EAC/B;AAAA,EAEA,GAAA,CAAO,SAAmB,EAAA,EAAgB;AACxC,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,OAAA,EAAS,EAAE,CAAA;AAAA,EACrC;AACF;;;ACbA,IAAM,uBAAA,GAA0B;AAAA,EAC9B,UAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,YAAA,GAAe,KAAA;AAQrB,SAAS,WAAA,CAAY,KAAa,QAAA,EAA6B;AAC7D,EAAA,MAAM,QAAA,GAAW,IAAI,WAAA,EAAY;AACjC,EAAA,OAAO,QAAA,CAAS,KAAK,CAAC,OAAA,KAAY,SAAS,QAAA,CAAS,OAAA,CAAQ,WAAA,EAAa,CAAC,CAAA;AAC5E;AAEA,SAAS,kBAAA,CAAmB,KAAa,IAAA,EAAsB;AAC7D,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,GAAG,CAAA;AAC1B,IAAA,IAAI,OAAO,QAAA,EAAU;AACnB,MAAA,MAAA,CAAO,QAAA,GAAW,IAAA;AAAA,IACpB;AACA,IAAA,IAAI,MAAA,CAAO,QAAA,IAAY,MAAA,CAAO,QAAA,EAAU;AACtC,MAAA,MAAA,CAAO,QAAA,GAAW,IAAA;AAAA,IACpB;AACA,IAAA,OAAO,OAAO,QAAA,EAAS;AAAA,EACzB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,GAAA;AAAA,EACT;AACF;AAEO,SAAS,WAAA,CACd,GAAA,EACA,OAAA,GAA8B,EAAC,EACtB;AACT,EAAA,MAAM,EAAE,QAAA,GAAW,uBAAA,EAAyB,OAAO,YAAA,EAAc,IAAA,GAAO,MAAK,GAAI,OAAA;AAEjF,EAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,GAAA,KAAQ,MAAA,EAAW;AACrC,IAAA,OAAO,GAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,QAAQ,QAAA,EAAU;AAC3B,IAAA,IAAI,IAAI,UAAA,CAAW,SAAS,KAAK,GAAA,CAAI,UAAA,CAAW,UAAU,CAAA,EAAG;AAC3D,MAAA,OAAO,kBAAA,CAAmB,KAAK,IAAI,CAAA;AAAA,IACrC;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAEA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG;AACtB,IAAA,OAAO,IAAA,GAAO,IAAI,GAAA,CAAI,CAAC,SAAS,WAAA,CAAY,IAAA,EAAM,OAAO,CAAC,CAAA,GAAI,GAAA;AAAA,EAChE;AAEA,EAAA,IAAI,OAAO,QAAQ,QAAA,EAAU;AAC3B,IAAA,MAAM,SAA2C,EAAC;AAGlD,IAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,qBAAA,CAAsB,GAAG,CAAA,EAAG;AACnD,MAAA,MAAA,CAAO,GAAG,CAAA,GAAK,GAAA,CAAgC,GAAG,CAAA;AAAA,IACpD;AAGA,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC9C,MAAA,IAAI,WAAA,CAAY,GAAA,EAAK,QAAQ,CAAA,EAAG;AAC9B,QAAA,MAAA,CAAO,GAAG,CAAA,GAAI,IAAA;AAAA,MAChB,WAAW,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,IAAY,UAAU,IAAA,EAAM;AAC9D,QAAA,MAAA,CAAO,GAAG,CAAA,GAAI,WAAA,CAAY,KAAA,EAAO,OAAO,CAAA;AAAA,MAC1C,CAAA,MAAA,IAAW,OAAO,KAAA,KAAU,QAAA,EAAU;AACpC,QAAA,MAAA,CAAO,GAAG,CAAA,GAAI,WAAA,CAAY,KAAA,EAAO,OAAO,CAAA;AAAA,MAC1C,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,GAAG,CAAA,GAAI,KAAA;AAAA,MAChB;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,YAAA,CAAa,OAAA,GAA8B,EAAC,EAAG;AAC7D,EAAA,OAAO,CAAC,GAAA,KAA0B,WAAA,CAAY,GAAA,EAAK,OAAO,CAAA;AAC5D;;;ACpFA,IAAM,eAAA,GAAkB,KAAA;AAExB,IAAM,YAAA,GAAuC;AAAA,EAC3C,KAAA,EAAO,UAAA;AAAA;AAAA,EACP,IAAA,EAAM,UAAA;AAAA;AAAA,EACN,IAAA,EAAM,UAAA;AAAA;AAAA,EACN,IAAA,EAAM,UAAA;AAAA;AAAA,EACN,OAAA,EAAS,UAAA;AAAA;AAAA,EACT,KAAA,EAAO,UAAA;AAAA;AAAA,EACP,KAAA,EAAO;AAAA;AACT,CAAA;AACA,IAAM,KAAA,GAAQ,SAAA;AAEd,SAAS,cAAc,KAAA,EAAuB;AAC5C,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,KAAK,CAAA,IAAK,EAAA;AACrC,EAAA,OAAO,QAAQ,CAAA,EAAG,KAAK,GAAG,KAAK,CAAA,EAAG,KAAK,CAAA,CAAA,GAAK,KAAA;AAC9C;AAEA,SAAS,UAAA,CAAW,MAA+B,MAAA,EAAyB;AAC1E,EAAA,OAAO,MAAA,CAAO,QAAQ,IAAI,CAAA,CACvB,OAAO,CAAC,GAAG,KAAK,CAAA,KAAM,UAAU,MAAA,IAAa,KAAA,KAAU,IAAI,CAAA,CAC3D,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AACrB,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,MAAA,MAAM,SAAA,GAAY,QAAQ,KAAA,EAAO,EAAE,OAAO,CAAA,EAAG,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAO,CAAA;AACrE,MAAA,OAAO;AAAA,EAAA,EAAO,GAAG,KAAK,SAAA,CAAU,KAAA,CAAM,IAAI,CAAA,CAAE,IAAA,CAAK,MAAM,CAAC,CAAA,CAAA;AAAA,IAC1D;AACA,IAAA,OAAO;AAAA,EAAA,EAAO,GAAG,KAAK,KAAK,CAAA,CAAA;AAAA,EAC7B,CAAC,CAAA,CACA,IAAA,CAAK,EAAE,CAAA;AACZ;AAEA,SAAS,gBAAgD,KAAA,EAA8C;AACrG,EAAA,OAAO,MAAA,CAAO,CAAC,IAAA,KAAS;AACtB,IAAA,MAAM,YAAA,GAAe,MAAM,QAAA,EAAS;AACpC,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,GAAG,YAAA,EAAa;AAAA,IACpC;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAC,CAAA,EAAE;AACL;AAEA,SAAS,kBAAkB,OAAA,EAA8C;AACvE,EAAA,OAAO,MAAA,CAAO,CAAC,IAAA,KAAS;AACtB,IAAA,OAAO,WAAA,CAAY,MAAM,OAAO,CAAA;AAAA,EAClC,CAAC,CAAA,EAAE;AACL;AAEO,SAAS,kBAAkD,KAAA,EAA8C;AAC9G,EAAA,OAAO,MAAA,CAAO,OAAA;AAAA,IACZ,MAAA,CAAO,MAAA,CAAO,EAAE,KAAA,EAAO,MAAM,CAAA;AAAA,IAC7B,OAAO,SAAA,EAAU;AAAA,IACjB,gBAAgB,KAAK,CAAA;AAAA,IACrB,iBAAA,EAAkB;AAAA,IAClB,MAAA,CAAO,MAAA,CAAO,CAAC,EAAE,SAAA,EAAW,OAAO,OAAA,EAAS,OAAA,EAAS,GAAG,IAAA,EAAK,KAAM;AACjE,MAAA,MAAM,aAAA,GAAgB,UAAA,CAAW,IAAA,EAAM,IAAI,CAAA;AAC3C,MAAA,MAAM,YAAA,GAAe,cAAc,KAAK,CAAA;AACxC,MAAA,OAAO,CAAA,CAAA,EAAI,SAAS,CAAA,EAAA,EAAK,YAAY,CAAA,EAAA,EAAK,WAAW,eAAe,CAAA,EAAA,EAAK,OAAO,CAAA,EAAG,aAAa,CAAA,CAAA;AAAA,IAClG,CAAC;AAAA,GACH;AACF;AAEO,SAAS,uBAAuD,KAAA,EAA8C;AACnH,EAAA,OAAO,MAAA,CAAO,OAAA;AAAA,IACZ,MAAA,CAAO,MAAA,CAAO,EAAE,KAAA,EAAO,MAAM,CAAA;AAAA,IAC7B,OAAO,SAAA,EAAU;AAAA,IACjB,gBAAgB,KAAK,CAAA;AAAA,IACrB,iBAAA,EAAkB;AAAA,IAClB,OAAO,IAAA;AAAK,GACd;AACF;AAEO,SAAS,YAAA,CAA6C,SAAkB,KAAA,EAA8C;AAC3H,EAAA,OAAO,OAAA,GAAU,iBAAA,CAAkB,KAAK,CAAA,GAAI,uBAAuB,KAAK,CAAA;AAC1E;ACzEO,SAAS,iBAAiB,MAAA,EAAmC;AAClE,EAAA,MAAM,MAAA,GAAsB,CAAC,IAAI,UAAA,CAAW,SAAS,CAAA;AAErD,EAAA,IAAI,OAAO,IAAA,EAAM;AACf,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,IAAI,eAAA,CAAgB;AAAA,QAClB,OAAA,EAAS,OAAO,IAAA,CAAK,OAAA;AAAA,QACrB,QAAA,EAAU,OAAO,IAAA,CAAK,QAAA;AAAA,QACtB,WAAA,EAAa,MAAA,CAAO,IAAA,CAAK,WAAA,IAAe,YAAA;AAAA,QACxC,aAAA,EAAe,MAAA,CAAO,IAAA,CAAK,aAAA,IAAiB,KAAA;AAAA,QAC5C,OAAA,EAAS,MAAA,CAAO,IAAA,CAAK,OAAA,IAAW,KAAA;AAAA,QAChC,QAAA,EAAU,MAAA,CAAO,IAAA,CAAK,QAAA,IAAY;AAAA,OACnC;AAAA,KACH;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,wBAAwB,MAAA,EAAmC;AACzE,EAAA,MAAM,MAAA,GAAsB,CAAC,IAAI,UAAA,CAAW,SAAS,CAAA;AAErD,EAAA,IAAI,OAAO,IAAA,EAAM;AACf,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,IAAI,eAAA,CAAgB;AAAA,QAClB,OAAA,EAAS,OAAO,IAAA,CAAK,OAAA;AAAA,QACrB,QAAA,EAAU,CAAA,WAAA,EAAc,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,CAAA;AAAA,QAC5C,WAAA,EAAa,MAAA,CAAO,IAAA,CAAK,WAAA,IAAe,YAAA;AAAA,QACxC,aAAA,EAAe,MAAA,CAAO,IAAA,CAAK,aAAA,IAAiB,KAAA;AAAA,QAC5C,OAAA,EAAS,MAAA,CAAO,IAAA,CAAK,OAAA,IAAW,KAAA;AAAA,QAChC,QAAA,EAAU,MAAA,CAAO,IAAA,CAAK,QAAA,IAAY;AAAA,OACnC;AAAA,KACH;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;;;AC1CO,IAAM,UAAA,GAAa;AAAA,EACxB,KAAA,EAAO,CAAA;AAAA,EACP,IAAA,EAAM,CAAA;AAAA,EACN,IAAA,EAAM,CAAA;AAAA,EACN,IAAA,EAAM,CAAA;AAAA,EACN,OAAA,EAAS,CAAA;AAAA,EACT,KAAA,EAAO,CAAA;AAAA,EACP,KAAA,EAAO;AACT;AAIO,SAAS,gBAAgB,KAAA,EAAkC;AAChE,EAAA,OAAO,KAAA,IAAS,UAAA;AAClB;AAEO,SAAS,eAAe,KAAA,EAA0C;AACvE,EAAA,IAAI,CAAC,eAAA,CAAgB,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,oBAAA,EAAuB,KAAK,CAAA,iBAAA,EAAoB,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,EACtG;AACF;;;ACAO,SAAS,WAAA,CACd,QACA,KAAA,EACuB;AACvB,EAAA,cAAA,CAAe,OAAO,KAAK,CAAA;AAE3B,EAAA,MAAM,WAAA,GAAc,KAAA,IAAS,IAAI,WAAA,EAAsB;AACvD,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,YAAA;AACzC,EAAA,MAAM,iBAAA,GAAoB,wBAAwB,MAAM,CAAA;AAExD,EAAA,MAAM,UAAU,YAAA,CAAa;AAAA,IAC3B,KAAA,EAAO,OAAA;AAAA;AAAA,IACP,MAAA,EAAQ,YAAA,CAAa,OAAA,EAAS,WAAW,CAAA;AAAA,IACzC,UAAA,EAAY,iBAAiB,MAAM,CAAA;AAAA,IACnC,iBAAA;AAAA,IACA,iBAAA,EAAmB,iBAAA;AAAA,IACnB,WAAA,EAAa;AAAA,GACd,CAAA;AAED,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,KAAA,EAAO,WAAA;AAAA,IACP,cAAc,MAAA,CAAO,KAAA;AAAA,IACrB,cAAA,sBAAoB,GAAA;AAAI,GAC1B;AACF;AAEO,SAAS,SAAA,CACd,OACA,KAAA,EACS;AACT,EAAA,MAAM,cAAA,GAAiB,kBAAkB,KAAK,CAAA;AAC9C,EAAA,OAAO,UAAA,CAAW,KAAK,CAAA,IAAK,UAAA,CAAW,cAAc,CAAA;AACvD;AAEA,SAAS,kBACP,KAAA,EACU;AACV,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,QAAA,EAAS;AACrC,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,KAAA,CAAM,YAAA;AAE3B,EAAA,KAAA,MAAW,EAAE,KAAA,EAAO,KAAA,MAAW,KAAA,CAAM,cAAA,CAAe,QAAO,EAAG;AAC5D,IAAA,IAAI,cAAA,CAAe,OAAA,EAAS,KAAK,CAAA,EAAG;AAClC,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,KAAA,CAAM,YAAA;AACf;AAEA,SAAS,cAAA,CACP,SACA,KAAA,EACS;AACT,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM,OAAA,CAAQ,GAAG,MAAM,KAAK,CAAA;AAC7E;;;ACtEO,IAAM,MAAA,GAAN,MAAM,OAAA,CAAuD;AAAA,EAC1D,WAAA,CACE,OACA,OAAA,EACR;AAFQ,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA,EACP;AAAA,EAEH,OAAO,MAAA,CACL,MAAA,EACA,KAAA,EACkB;AAClB,IAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,MAAA,EAAQ,KAAK,CAAA;AACvC,IAAA,OAAO,IAAI,OAAA,CAAO,KAAA,EAAO,KAAK,CAAA;AAAA,EAChC;AAAA,EAEA,MAAM,OAAA,EAAmC;AACvC,IAAA,OAAO,IAAI,OAAA,CAAO,IAAA,CAAK,KAAA,EAAO,OAAO,CAAA;AAAA,EACvC;AAAA;AAAA,EAIA,QAAA,GAAkC;AAChC,IAAA,OAAO,KAAK,KAAA,CAAM,KAAA;AAAA,EACpB;AAAA,EAEA,gBAAA,CAAiB,OAA0B,KAAA,EAAuB;AAChE,IAAA,cAAA,CAAe,KAAK,CAAA;AACpB,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAChC,IAAA,IAAA,CAAK,MAAM,cAAA,CAAe,GAAA,CAAI,KAAK,EAAE,KAAA,EAAO,OAAO,CAAA;AAAA,EACrD;AAAA,EAEA,oBAAoB,KAAA,EAAgC;AAClD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAChC,IAAA,IAAA,CAAK,KAAA,CAAM,cAAA,CAAe,MAAA,CAAO,GAAG,CAAA;AAAA,EACtC;AAAA,EAEA,mBAAA,GAA4B;AAC1B,IAAA,IAAA,CAAK,KAAA,CAAM,eAAe,KAAA,EAAM;AAAA,EAClC;AAAA,EAEA,iBAAA,GAA+C;AAC7C,IAAA,OAAO,MAAM,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,cAAA,CAAe,QAAQ,CAAA;AAAA,EACtD;AAAA;AAAA,EAIA,OAAA,CAAQ,IAAY,IAAA,EAAqB;AACvC,IAAA,IAAA,CAAK,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,EAAA,EAAI,IAAI,CAAA;AAAA,EACrC;AAAA;AAAA,EAIA,KAAA,CAAM,OAAA,EAAiB,KAAA,EAAyB,IAAA,EAAqB;AACnE,IAAA,IAAI,CAAC,SAAA,CAAU,IAAA,CAAK,KAAA,EAAO,OAAO,CAAA,EAAG;AACrC,IAAA,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,OAAA,EAAS,IAAA,EAAM,KAAK,CAAA;AAAA,EACxC;AAAA,EAEA,IAAA,CAAK,SAAiB,IAAA,EAAqB;AACzC,IAAA,IAAI,CAAC,SAAA,CAAU,IAAA,CAAK,KAAA,EAAO,MAAM,CAAA,EAAG;AACpC,IAAA,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,OAAA,EAAS,IAAI,CAAA;AAAA,EAChC;AAAA,EAEA,IAAA,CAAK,SAAiB,IAAA,EAAqB;AACzC,IAAA,IAAI,CAAC,SAAA,CAAU,IAAA,CAAK,KAAA,EAAO,MAAM,CAAA,EAAG;AACpC,IAAA,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,OAAA,EAAS,IAAI,CAAA;AAAA,EAChC;AAAA,EAEA,IAAA,CAAK,SAAiB,IAAA,EAAqB;AACzC,IAAA,IAAI,CAAC,SAAA,CAAU,IAAA,CAAK,KAAA,EAAO,MAAM,CAAA,EAAG;AACpC,IAAA,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,OAAA,EAAS,IAAI,CAAA;AAAA,EAChC;AAAA,EAEA,OAAA,CAAQ,SAAiB,IAAA,EAAqB;AAC5C,IAAA,IAAI,CAAC,SAAA,CAAU,IAAA,CAAK,KAAA,EAAO,SAAS,CAAA,EAAG;AACvC,IAAA,IAAA,CAAK,GAAA,CAAI,SAAA,EAAW,OAAA,EAAS,IAAI,CAAA;AAAA,EACnC;AAAA,EAEA,KAAA,CAAM,SAAiB,IAAA,EAAqB;AAC1C,IAAA,IAAI,CAAC,SAAA,CAAU,IAAA,CAAK,KAAA,EAAO,OAAO,CAAA,EAAG;AACrC,IAAA,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,OAAA,EAAS,IAAI,CAAA;AAAA,EACjC;AAAA,EAEA,KAAA,CAAM,SAAiB,IAAA,EAAqB;AAC1C,IAAA,IAAI,CAAC,SAAA,CAAU,IAAA,CAAK,KAAA,EAAO,OAAO,CAAA,EAAG;AACrC,IAAA,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,OAAA,EAAS,IAAI,CAAA;AAAA,EACjC;AAAA;AAAA,EAIQ,GAAA,CAAI,KAAA,EAAiB,OAAA,EAAiB,IAAA,EAAe,KAAA,EAA+B;AAC1F,IAAA,MAAM,UAAmC,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAS,GAAG,IAAA,EAAK;AAE1E,IAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,MAAA,OAAA,CAAQ,eAAe,KAAA,CAAM,OAAA;AAC7B,MAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,KAAA;AAAA,IACxB,CAAA,MAAA,IAAW,UAAU,MAAA,EAAW;AAC9B,MAAA,OAAA,CAAQ,KAAA,GAAQ,KAAA;AAAA,IAClB;AAEA,IAAA,IAAA,CAAK,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,KAAA,EAAO,SAAS,OAAO,CAAA;AAAA,EAChD;AACF;;;ACzFO,SAAS,qBAAA,GAEe;AAC7B,EAAA,IAAI,IAAA,GAAgC,IAAA;AAEpC,EAAA,MAAM,aAAa,MAAwB;AACzC,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,IACpE;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,CAAK,QAAsB,KAAA,EAAiD;AAC1E,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,MAAA,EAAQ,KAAK,CAAA;AAAA,MACpC;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AAAA,IAEA,GAAA,GAAwB;AACtB,MAAA,OAAO,UAAA,EAAW;AAAA,IACpB,CAAA;AAAA,IAEA,MAAM,OAAA,EAAmC;AACvC,MAAA,OAAO,UAAA,EAAW,CAAE,KAAA,CAAM,OAAO,CAAA;AAAA,IACnC,CAAA;AAAA,IAEA,QAAA,GAAkC;AAChC,MAAA,OAAO,UAAA,GAAa,QAAA,EAAS;AAAA,IAC/B,CAAA;AAAA,IAEA,gBAAA,CAAiB,OAA0B,KAAA,EAAuB;AAChE,MAAA,UAAA,EAAW,CAAE,gBAAA,CAAiB,KAAA,EAAO,KAAK,CAAA;AAAA,IAC5C,CAAA;AAAA,IAEA,oBAAoB,KAAA,EAAgC;AAClD,MAAA,UAAA,EAAW,CAAE,oBAAoB,KAAK,CAAA;AAAA,IACxC,CAAA;AAAA,IAEA,iBAAA,GAA+C;AAC7C,MAAA,OAAO,UAAA,GAAa,iBAAA,EAAkB;AAAA,IACxC,CAAA;AAAA,IAEA,mBAAA,GAA4B;AAC1B,MAAA,UAAA,GAAa,mBAAA,EAAoB;AAAA,IACnC;AAAA,GACF;AACF;;;ACrDA,SAAS,eAAe,EAAA,EAAoB;AAC1C,EAAA,IAAI,KAAK,GAAA,EAAM;AACb,IAAA,OAAO,CAAA,EAAG,EAAA,CAAG,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAA;AAAA,EACzB;AACA,EAAA,IAAI,KAAK,GAAA,EAAO;AACd,IAAA,OAAO,CAAA,EAAA,CAAI,EAAA,GAAK,GAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AAAA,EAClC;AACA,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,GAAK,CAAA;AACrC,EAAA,MAAM,OAAA,GAAA,CAAY,EAAA,GAAK,GAAA,GAAS,GAAA,EAAM,QAAQ,CAAC,CAAA;AAC/C,EAAA,OAAO,CAAA,EAAG,OAAO,CAAA,EAAA,EAAK,OAAO,CAAA,CAAA,CAAA;AAC/B;AAEO,SAAS,YAAY,KAAA,EAAsB;AAChD,EAAA,MAAM,KAAA,GAAQ,YAAY,GAAA,EAAI;AAE9B,EAAA,OAAO;AAAA,IACL,GAAA,GAAoB;AAClB,MAAA,MAAM,UAAA,GAAa,WAAA,CAAY,GAAA,EAAI,GAAI,KAAA;AACvC,MAAA,OAAO;AAAA,QACL,KAAA;AAAA,QACA,UAAA;AAAA,QACA,iBAAA,EAAmB,eAAe,UAAU;AAAA,OAC9C;AAAA,IACF;AAAA,GACF;AACF;AAEA,eAAsB,YAAA,CACpB,OACA,EAAA,EAC8C;AAC9C,EAAA,MAAM,KAAA,GAAQ,YAAY,KAAK,CAAA;AAC/B,EAAA,MAAM,MAAA,GAAS,MAAM,EAAA,EAAG;AACxB,EAAA,MAAM,MAAA,GAAS,MAAM,GAAA,EAAI;AACzB,EAAA,OAAO,EAAE,QAAQ,MAAA,EAAO;AAC1B;AAEO,SAAS,WAAA,CACd,OACA,EAAA,EACqC;AACrC,EAAA,MAAM,KAAA,GAAQ,YAAY,KAAK,CAAA;AAC/B,EAAA,MAAM,SAAS,EAAA,EAAG;AAClB,EAAA,MAAM,MAAA,GAAS,MAAM,GAAA,EAAI;AACzB,EAAA,OAAO,EAAE,QAAQ,MAAA,EAAO;AAC1B;AChDO,SAAS,iBAAA,CAAkB,OAAA,GAA4B,EAAC,EAAW;AACxE,EAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,GAAQ,KAAA,EAAM,GAAI,OAAA;AAClC,EAAA,MAAM,OAAO,UAAA,EAAW;AACxB,EAAA,MAAM,KAAK,KAAA,GAAQ,IAAA,CAAK,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,GAAI,IAAA;AACxC,EAAA,OAAO,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,GAAK,EAAA;AACtC;AAEO,SAAS,iBAAiB,OAAA,EAA4E;AAC3G,EAAA,MAAM,WAAA,GAAc,CAAC,cAAA,EAAgB,kBAAA,EAAoB,YAAY,CAAA;AAErE,EAAA,KAAA,MAAW,QAAQ,WAAA,EAAa;AAC9B,IAAA,MAAM,KAAA,GAAQ,QAAQ,IAAI,CAAA;AAC1B,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,SAAS,CAAA,EAAG;AACjD,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,SAAS,CAAA,EAAG;AAC5C,MAAA,OAAO,MAAM,CAAC,CAAA;AAAA,IAChB;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,sBAAA,CACd,OAAA,EACA,OAAA,GAA4B,EAAC,EACrB;AACR,EAAA,OAAO,gBAAA,CAAiB,OAAO,CAAA,IAAK,iBAAA,CAAkB,OAAO,CAAA;AAC/D","file":"index.mjs","sourcesContent":["import { AsyncLocalStorage } from 'async_hooks';\nimport type { LoggerContext } from './types.js';\n\nexport class LoggerStore<TContext extends LoggerContext = LoggerContext> {\n private storage = new AsyncLocalStorage<TContext>();\n\n getStore(): TContext | undefined {\n return this.storage.getStore();\n }\n\n run<T>(context: TContext, fn: () => T): T {\n return this.storage.run(context, fn);\n }\n}\n","const DEFAULT_SECRET_PATTERNS = [\n 'password',\n 'secret',\n 'token',\n 'apikey',\n 'api_key',\n 'api-key',\n 'auth',\n 'credential',\n 'private',\n];\n\nconst DEFAULT_MASK = '***';\n\nexport interface MaskSecretsOptions {\n patterns?: string[];\n mask?: string;\n deep?: boolean;\n}\n\nfunction isSecretKey(key: string, patterns: string[]): boolean {\n const lowerKey = key.toLowerCase();\n return patterns.some((pattern) => lowerKey.includes(pattern.toLowerCase()));\n}\n\nfunction maskUrlCredentials(url: string, mask: string): string {\n try {\n const parsed = new URL(url);\n if (parsed.password) {\n parsed.password = mask;\n }\n if (parsed.username && parsed.password) {\n parsed.username = mask;\n }\n return parsed.toString();\n } catch {\n return url;\n }\n}\n\nexport function maskSecrets(\n obj: unknown,\n options: MaskSecretsOptions = {},\n): unknown {\n const { patterns = DEFAULT_SECRET_PATTERNS, mask = DEFAULT_MASK, deep = true } = options;\n\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (typeof obj === 'string') {\n if (obj.startsWith('http://') || obj.startsWith('https://')) {\n return maskUrlCredentials(obj, mask);\n }\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return deep ? obj.map((item) => maskSecrets(item, options)) : obj;\n }\n\n if (typeof obj === 'object') {\n const result: Record<string | symbol, unknown> = {};\n\n // Copy Symbol properties first (important for Winston's internal symbols)\n for (const sym of Object.getOwnPropertySymbols(obj)) {\n result[sym] = (obj as Record<symbol, unknown>)[sym];\n }\n\n // Process string keys\n for (const [key, value] of Object.entries(obj)) {\n if (isSecretKey(key, patterns)) {\n result[key] = mask;\n } else if (deep && typeof value === 'object' && value !== null) {\n result[key] = maskSecrets(value, options);\n } else if (typeof value === 'string') {\n result[key] = maskSecrets(value, options);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n }\n\n return obj;\n}\n\nexport function createMasker(options: MaskSecretsOptions = {}) {\n return (obj: unknown): unknown => maskSecrets(obj, options);\n}\n","import { inspect } from 'util';\nimport { format, Logform } from 'winston';\nimport { LoggerStore } from './store.js';\nimport type { LoggerContext } from './types.js';\nimport { maskSecrets, type MaskSecretsOptions } from './utils/mask-secrets.js';\n\nconst DEFAULT_CONTEXT = 'APP';\n\nconst LEVEL_COLORS: Record<string, string> = {\n error: '\\x1b[31m', // red\n warn: '\\x1b[33m', // yellow\n info: '\\x1b[32m', // green\n http: '\\x1b[35m', // magenta\n verbose: '\\x1b[36m', // cyan\n debug: '\\x1b[34m', // blue\n silly: '\\x1b[90m', // grey\n};\nconst RESET = '\\x1b[0m';\n\nfunction colorizeLevel(level: string): string {\n const color = LEVEL_COLORS[level] || '';\n return color ? `${color}${level}${RESET}` : level;\n}\n\nfunction formatMeta(meta: Record<string, unknown>, colors: boolean): string {\n return Object.entries(meta)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => {\n if (typeof value === 'object') {\n const inspected = inspect(value, { depth: 4, colors, compact: false });\n return `\\n ${key}: ${inspected.split('\\n').join('\\n ')}`;\n }\n return `\\n ${key}: ${value}`;\n })\n .join('');\n}\n\nfunction addStoreContext<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format((info) => {\n const storeContext = store.getStore();\n if (storeContext) {\n return { ...info, ...storeContext };\n }\n return info;\n })();\n}\n\nfunction maskSecretsFormat(options?: MaskSecretsOptions): Logform.Format {\n return format((info) => {\n return maskSecrets(info, options) as Logform.TransformableInfo;\n })();\n}\n\nexport function createLocalFormat<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format.combine(\n format.errors({ stack: true }),\n format.timestamp(),\n addStoreContext(store),\n maskSecretsFormat(),\n format.printf(({ timestamp, level, context, message, ...meta }) => {\n const formattedMeta = formatMeta(meta, true);\n const coloredLevel = colorizeLevel(level);\n return `[${timestamp}] ${coloredLevel} [${context || DEFAULT_CONTEXT}] ${message}${formattedMeta}`;\n }),\n );\n}\n\nexport function createProductionFormat<TContext extends LoggerContext>(store: LoggerStore<TContext>): Logform.Format {\n return format.combine(\n format.errors({ stack: true }),\n format.timestamp(),\n addStoreContext(store),\n maskSecretsFormat(),\n format.json(),\n );\n}\n\nexport function createFormat<TContext extends LoggerContext>(isLocal: boolean, store: LoggerStore<TContext>): Logform.Format {\n return isLocal ? createLocalFormat(store) : createProductionFormat(store);\n}\n","import { transports } from 'winston';\nimport DailyRotateFile from 'winston-daily-rotate-file';\nimport type { LoggerConfig } from './types.js';\n\ntype Transport = transports.ConsoleTransportInstance | DailyRotateFile;\n\nexport function createTransports(config: LoggerConfig): Transport[] {\n const result: Transport[] = [new transports.Console()];\n\n if (config.file) {\n result.push(\n new DailyRotateFile({\n dirname: config.file.dirname,\n filename: config.file.filename,\n datePattern: config.file.datePattern ?? 'YYYY-MM-DD',\n zippedArchive: config.file.zippedArchive ?? false,\n maxSize: config.file.maxSize ?? '20m',\n maxFiles: config.file.maxFiles ?? '14d',\n }),\n );\n }\n\n return result;\n}\n\nexport function createExceptionHandlers(config: LoggerConfig): Transport[] {\n const result: Transport[] = [new transports.Console()];\n\n if (config.file) {\n result.push(\n new DailyRotateFile({\n dirname: config.file.dirname,\n filename: `exceptions-${config.file.filename}`,\n datePattern: config.file.datePattern ?? 'YYYY-MM-DD',\n zippedArchive: config.file.zippedArchive ?? false,\n maxSize: config.file.maxSize ?? '20m',\n maxFiles: config.file.maxFiles ?? '14d',\n }),\n );\n }\n\n return result;\n}\n","export const LOG_LEVELS = {\n error: 0,\n warn: 1,\n info: 2,\n http: 3,\n verbose: 4,\n debug: 5,\n silly: 6,\n} as const;\n\nexport type LogLevel = keyof typeof LOG_LEVELS;\n\nexport function isValidLogLevel(level: string): level is LogLevel {\n return level in LOG_LEVELS;\n}\n\nexport function assertLogLevel(level: string): asserts level is LogLevel {\n if (!isValidLogLevel(level)) {\n throw new Error(`Invalid log level: \"${level}\". Valid levels: ${Object.keys(LOG_LEVELS).join(', ')}`);\n }\n}\n\nexport interface FileConfig {\n dirname: string;\n filename: string;\n datePattern?: string;\n zippedArchive?: boolean;\n maxSize?: string;\n maxFiles?: string;\n}\n\nexport interface LoggerConfig {\n level: LogLevel;\n file?: FileConfig;\n}\n\nexport type LoggerContext = Record<string, unknown>;\n\nexport interface LevelOverride<TContext extends LoggerContext> {\n match: Partial<TContext>;\n level: LogLevel;\n}\n","import { createLogger, type Logger as WinstonLogger } from 'winston';\nimport { LoggerStore } from './store.js';\nimport { createFormat } from './formatters.js';\nimport { createTransports, createExceptionHandlers } from './transports.js';\nimport {\n LOG_LEVELS,\n assertLogLevel,\n type LoggerConfig,\n type LoggerContext,\n type LevelOverride,\n type LogLevel,\n} from './types.js';\n\nexport interface LoggerState<TContext extends LoggerContext> {\n winston: WinstonLogger;\n store: LoggerStore<TContext>;\n defaultLevel: LogLevel;\n levelOverrides: Map<string, LevelOverride<TContext>>;\n}\n\nexport function createState<TContext extends LoggerContext>(\n config: LoggerConfig,\n store?: LoggerStore<TContext>,\n): LoggerState<TContext> {\n assertLogLevel(config.level);\n\n const loggerStore = store ?? new LoggerStore<TContext>();\n const isLocal = process.env.NODE_ENV !== 'production';\n const exceptionHandlers = createExceptionHandlers(config);\n\n const winston = createLogger({\n level: 'silly', // Accept all, we filter in shouldLog()\n format: createFormat(isLocal, loggerStore),\n transports: createTransports(config),\n exceptionHandlers,\n rejectionHandlers: exceptionHandlers,\n exitOnError: false,\n });\n\n return {\n winston,\n store: loggerStore,\n defaultLevel: config.level,\n levelOverrides: new Map(),\n };\n}\n\nexport function shouldLog<TContext extends LoggerContext>(\n state: LoggerState<TContext>,\n level: LogLevel,\n): boolean {\n const effectiveLevel = getEffectiveLevel(state);\n return LOG_LEVELS[level] <= LOG_LEVELS[effectiveLevel];\n}\n\nfunction getEffectiveLevel<TContext extends LoggerContext>(\n state: LoggerState<TContext>,\n): LogLevel {\n const context = state.store.getStore();\n if (!context) return state.defaultLevel;\n\n for (const { match, level } of state.levelOverrides.values()) {\n if (matchesContext(context, match)) {\n return level;\n }\n }\n return state.defaultLevel;\n}\n\nfunction matchesContext<TContext extends LoggerContext>(\n context: TContext,\n match: Partial<TContext>,\n): boolean {\n return Object.entries(match).every(([key, value]) => context[key] === value);\n}\n","import { LoggerStore } from './store.js';\nimport { createState, shouldLog, type LoggerState } from './state.js';\nimport { assertLogLevel, type LoggerConfig, type LoggerContext, type LevelOverride, type LogLevel } from './types.js';\n\nexport class Logger<TContext extends LoggerContext = LoggerContext> {\n private constructor(\n private state: LoggerState<TContext>,\n private context: string,\n ) {}\n\n static create<TContext extends LoggerContext = LoggerContext>(\n config: LoggerConfig,\n store?: LoggerStore<TContext>,\n ): Logger<TContext> {\n const state = createState(config, store);\n return new Logger(state, 'APP');\n }\n\n child(context: string): Logger<TContext> {\n return new Logger(this.state, context);\n }\n\n // State accessors\n\n getStore(): LoggerStore<TContext> {\n return this.state.store;\n }\n\n setLevelOverride(match: Partial<TContext>, level: LogLevel): void {\n assertLogLevel(level);\n const key = JSON.stringify(match);\n this.state.levelOverrides.set(key, { match, level });\n }\n\n removeLevelOverride(match: Partial<TContext>): void {\n const key = JSON.stringify(match);\n this.state.levelOverrides.delete(key);\n }\n\n clearLevelOverrides(): void {\n this.state.levelOverrides.clear();\n }\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return Array.from(this.state.levelOverrides.values());\n }\n\n // Profiling\n\n profile(id: string, meta?: object): void {\n this.state.winston.profile(id, meta);\n }\n\n // Logging methods\n\n error(message: string, error?: Error | unknown, meta?: object): void {\n if (!shouldLog(this.state, 'error')) return;\n this.log('error', message, meta, error);\n }\n\n warn(message: string, meta?: object): void {\n if (!shouldLog(this.state, 'warn')) return;\n this.log('warn', message, meta);\n }\n\n info(message: string, meta?: object): void {\n if (!shouldLog(this.state, 'info')) return;\n this.log('info', message, meta);\n }\n\n http(message: string, meta?: object): void {\n if (!shouldLog(this.state, 'http')) return;\n this.log('http', message, meta);\n }\n\n verbose(message: string, meta?: object): void {\n if (!shouldLog(this.state, 'verbose')) return;\n this.log('verbose', message, meta);\n }\n\n debug(message: string, meta?: object): void {\n if (!shouldLog(this.state, 'debug')) return;\n this.log('debug', message, meta);\n }\n\n silly(message: string, meta?: object): void {\n if (!shouldLog(this.state, 'silly')) return;\n this.log('silly', message, meta);\n }\n\n // Private\n\n private log(level: LogLevel, message: string, meta?: object, error?: Error | unknown): void {\n const logMeta: Record<string, unknown> = { context: this.context, ...meta };\n\n if (error instanceof Error) {\n logMeta.errorMessage = error.message;\n logMeta.stack = error.stack;\n } else if (error !== undefined) {\n logMeta.error = error;\n }\n\n this.state.winston.log(level, message, logMeta);\n }\n}\n","import { Logger } from './logger.js';\nimport { LoggerStore } from './store.js';\nimport type { LoggerConfig, LoggerContext, LevelOverride, LogLevel } from './types.js';\n\nexport interface SingletonLogger<TContext extends LoggerContext> {\n init(config: LoggerConfig, store?: LoggerStore<TContext>): Logger<TContext>;\n get(): Logger<TContext>;\n child(context: string): Logger<TContext>;\n getStore(): LoggerStore<TContext>;\n setLevelOverride(match: Partial<TContext>, level: LogLevel): void;\n removeLevelOverride(match: Partial<TContext>): void;\n getLevelOverrides(): LevelOverride<TContext>[];\n clearLevelOverrides(): void;\n}\n\nexport function createSingletonLogger<\n TContext extends LoggerContext = LoggerContext,\n>(): SingletonLogger<TContext> {\n let root: Logger<TContext> | null = null;\n\n const ensureInit = (): Logger<TContext> => {\n if (!root) {\n throw new Error('Logger not initialized. Call init(config) first.');\n }\n return root;\n };\n\n return {\n init(config: LoggerConfig, store?: LoggerStore<TContext>): Logger<TContext> {\n if (!root) {\n root = Logger.create(config, store);\n }\n return root;\n },\n\n get(): Logger<TContext> {\n return ensureInit();\n },\n\n child(context: string): Logger<TContext> {\n return ensureInit().child(context);\n },\n\n getStore(): LoggerStore<TContext> {\n return ensureInit().getStore();\n },\n\n setLevelOverride(match: Partial<TContext>, level: LogLevel): void {\n ensureInit().setLevelOverride(match, level);\n },\n\n removeLevelOverride(match: Partial<TContext>): void {\n ensureInit().removeLevelOverride(match);\n },\n\n getLevelOverrides(): LevelOverride<TContext>[] {\n return ensureInit().getLevelOverrides();\n },\n\n clearLevelOverrides(): void {\n ensureInit().clearLevelOverrides();\n },\n };\n}\n","export interface TimingResult {\n label: string;\n durationMs: number;\n durationFormatted: string;\n}\n\nexport interface Timer {\n end: () => TimingResult;\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms.toFixed(2)}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(1);\n return `${minutes}m ${seconds}s`;\n}\n\nexport function createTimer(label: string): Timer {\n const start = performance.now();\n\n return {\n end(): TimingResult {\n const durationMs = performance.now() - start;\n return {\n label,\n durationMs,\n durationFormatted: formatDuration(durationMs),\n };\n },\n };\n}\n\nexport async function measureAsync<T>(\n label: string,\n fn: () => Promise<T>,\n): Promise<{ result: T; timing: TimingResult }> {\n const timer = createTimer(label);\n const result = await fn();\n const timing = timer.end();\n return { result, timing };\n}\n\nexport function measureSync<T>(\n label: string,\n fn: () => T,\n): { result: T; timing: TimingResult } {\n const timer = createTimer(label);\n const result = fn();\n const timing = timer.end();\n return { result, timing };\n}\n","import { randomUUID } from 'crypto';\n\nexport interface RequestIdOptions {\n prefix?: string;\n short?: boolean;\n}\n\nexport function generateRequestId(options: RequestIdOptions = {}): string {\n const { prefix, short = false } = options;\n const uuid = randomUUID();\n const id = short ? uuid.split('-')[0] : uuid;\n return prefix ? `${prefix}-${id}` : id;\n}\n\nexport function extractRequestId(headers: Record<string, string | string[] | undefined>): string | undefined {\n const headerNames = ['x-request-id', 'x-correlation-id', 'x-trace-id'];\n\n for (const name of headerNames) {\n const value = headers[name];\n if (typeof value === 'string' && value.length > 0) {\n return value;\n }\n if (Array.isArray(value) && value.length > 0) {\n return value[0];\n }\n }\n\n return undefined;\n}\n\nexport function getOrGenerateRequestId(\n headers: Record<string, string | string[] | undefined>,\n options: RequestIdOptions = {},\n): string {\n return extractRequestId(headers) ?? generateRequestId(options);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rawnodes/logger",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Flexible Winston-based logger with AsyncLocalStorage context, level overrides, and timing utilities",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -22,15 +22,6 @@
22
22
  "README.md",
23
23
  "LICENSE"
24
24
  ],
25
- "scripts": {
26
- "build": "tsup",
27
- "dev": "tsup --watch",
28
- "test": "vitest run",
29
- "test:watch": "vitest",
30
- "test:coverage": "vitest run --coverage",
31
- "lint": "eslint src --ext .ts",
32
- "prepublishOnly": "pnpm build"
33
- },
34
25
  "keywords": [
35
26
  "logger",
36
27
  "logging",
@@ -59,5 +50,13 @@
59
50
  "tsup": "^8.0.0",
60
51
  "typescript": "^5.7.0",
61
52
  "vitest": "^2.0.0"
53
+ },
54
+ "scripts": {
55
+ "build": "tsup",
56
+ "dev": "tsup --watch",
57
+ "test": "vitest run",
58
+ "test:watch": "vitest",
59
+ "test:coverage": "vitest run --coverage",
60
+ "lint": "eslint src --ext .ts"
62
61
  }
63
- }
62
+ }