logixia 1.0.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.js ADDED
@@ -0,0 +1,1151 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __commonJS = (cb, mod) => function() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
13
+ key = keys[i];
14
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
15
+ get: ((k) => from[k]).bind(null, key),
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
22
+ value: mod,
23
+ enumerable: true
24
+ }) : target, mod));
25
+
26
+ //#endregion
27
+ let uuid = require("uuid");
28
+ uuid = __toESM(uuid);
29
+ let async_hooks = require("async_hooks");
30
+ async_hooks = __toESM(async_hooks);
31
+ let __nestjs_common = require("@nestjs/common");
32
+ __nestjs_common = __toESM(__nestjs_common);
33
+
34
+ //#region src/types/index.ts
35
+ const LogLevel = {
36
+ ERROR: "error",
37
+ WARN: "warn",
38
+ INFO: "info",
39
+ DEBUG: "debug",
40
+ TRACE: "trace",
41
+ VERBOSE: "verbose"
42
+ };
43
+ const DEFAULT_LOG_LEVELS = {
44
+ error: 0,
45
+ warn: 1,
46
+ info: 2,
47
+ debug: 3,
48
+ trace: 4,
49
+ verbose: 5
50
+ };
51
+ const DEFAULT_LOG_COLORS = {
52
+ error: "red",
53
+ warn: "yellow",
54
+ info: "green",
55
+ debug: "blue",
56
+ trace: "magenta",
57
+ verbose: "cyan"
58
+ };
59
+
60
+ //#endregion
61
+ //#region src/utils/trace.utils.ts
62
+ const traceStorage = new async_hooks.AsyncLocalStorage();
63
+ /**
64
+ * Default trace ID generator using UUID v4
65
+ */
66
+ function generateTraceId() {
67
+ return (0, uuid.v4)().replace(/-/g, "").substring(0, 16);
68
+ }
69
+ /**
70
+ * Get current trace ID from async context
71
+ */
72
+ function getCurrentTraceId() {
73
+ const store = traceStorage.getStore();
74
+ return store === null || store === void 0 ? void 0 : store.traceId;
75
+ }
76
+ /**
77
+ * Set trace ID in async context
78
+ */
79
+ function setTraceId(traceId, data) {
80
+ const currentStore = traceStorage.getStore() || {};
81
+ traceStorage.enterWith({
82
+ ...currentStore,
83
+ traceId,
84
+ ...data
85
+ });
86
+ }
87
+ /**
88
+ * Run function with trace ID context
89
+ */
90
+ function runWithTraceId(traceId, fn, data) {
91
+ return traceStorage.run({
92
+ traceId,
93
+ ...data
94
+ }, fn);
95
+ }
96
+ /**
97
+ * Extract trace ID from request using configuration
98
+ */
99
+ function extractTraceId(request, config) {
100
+ if (config.header) {
101
+ const headers = Array.isArray(config.header) ? config.header : [config.header];
102
+ for (const header of headers) {
103
+ var _request$headers;
104
+ const value = (_request$headers = request.headers) === null || _request$headers === void 0 ? void 0 : _request$headers[header.toLowerCase()];
105
+ if (value) return Array.isArray(value) ? value[0] : value;
106
+ }
107
+ }
108
+ if (config.query) {
109
+ const queries = Array.isArray(config.query) ? config.query : [config.query];
110
+ for (const query of queries) {
111
+ var _request$query;
112
+ const value = (_request$query = request.query) === null || _request$query === void 0 ? void 0 : _request$query[query];
113
+ if (value) return Array.isArray(value) ? value[0] : value;
114
+ }
115
+ }
116
+ if (config.body) {
117
+ const bodyFields = Array.isArray(config.body) ? config.body : [config.body];
118
+ for (const field of bodyFields) {
119
+ var _request$body;
120
+ const value = (_request$body = request.body) === null || _request$body === void 0 ? void 0 : _request$body[field];
121
+ if (value) return value;
122
+ }
123
+ }
124
+ if (config.params) {
125
+ const paramFields = Array.isArray(config.params) ? config.params : [config.params];
126
+ for (const param of paramFields) {
127
+ var _request$params;
128
+ const value = (_request$params = request.params) === null || _request$params === void 0 ? void 0 : _request$params[param];
129
+ if (value) return value;
130
+ }
131
+ }
132
+ }
133
+ /**
134
+ * Create trace ID middleware for Express/NestJS
135
+ */
136
+ function createTraceMiddleware(config) {
137
+ return (req, res, next) => {
138
+ let traceId;
139
+ if (config.extractor) traceId = extractTraceId(req, config.extractor);
140
+ if (!traceId) traceId = config.generator ? config.generator() : generateTraceId();
141
+ req.traceId = traceId;
142
+ res.setHeader("X-Trace-Id", traceId);
143
+ runWithTraceId(traceId, () => {
144
+ next();
145
+ }, { requestId: req.id || generateTraceId() });
146
+ };
147
+ }
148
+
149
+ //#endregion
150
+ //#region src/utils/error.utils.ts
151
+ /**
152
+ * Serialize error object to JSON-safe format
153
+ */
154
+ function serializeError(error, options = {}) {
155
+ const { includeStack = true, maxDepth = 3, excludeFields = [] } = options;
156
+ const serialized = {
157
+ name: error.name,
158
+ message: error.message
159
+ };
160
+ if (includeStack && error.stack) serialized.stack = error.stack;
161
+ const errorKeys = Object.getOwnPropertyNames(error);
162
+ for (const key of errorKeys) if (key !== "name" && key !== "message" && key !== "stack" && !excludeFields.includes(key)) try {
163
+ const value = error[key];
164
+ serialized[key] = serializeValue(value, maxDepth);
165
+ } catch {}
166
+ return serialized;
167
+ }
168
+ /**
169
+ * Recursively serialize values with depth limit
170
+ */
171
+ function serializeValue(value, maxDepth, currentDepth = 0) {
172
+ if (currentDepth >= maxDepth) return "[Max Depth Reached]";
173
+ if (value === null || value === void 0) return value;
174
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
175
+ if (value instanceof Date) return value.toISOString();
176
+ if (value instanceof Error) return serializeError(value, { maxDepth: maxDepth - currentDepth });
177
+ if (Array.isArray(value)) return value.map((item) => serializeValue(item, maxDepth, currentDepth + 1));
178
+ if (typeof value === "object") {
179
+ const serialized = {};
180
+ for (const [key, val] of Object.entries(value)) try {
181
+ serialized[key] = serializeValue(val, maxDepth, currentDepth + 1);
182
+ } catch {
183
+ serialized[key] = "[Unserializable]";
184
+ }
185
+ return serialized;
186
+ }
187
+ return String(value);
188
+ }
189
+ /**
190
+ * Check if value is an Error instance
191
+ */
192
+ function isError(value) {
193
+ return value instanceof Error || value && typeof value === "object" && "name" in value && "message" in value;
194
+ }
195
+ /**
196
+ * Create error from various input types
197
+ */
198
+ function normalizeError(error) {
199
+ if (isError(error)) return error;
200
+ if (typeof error === "string") return new Error(error);
201
+ if (typeof error === "object" && error !== null) {
202
+ const err = new Error(error.message || "Unknown error");
203
+ Object.assign(err, error);
204
+ return err;
205
+ }
206
+ return new Error(String(error));
207
+ }
208
+
209
+ //#endregion
210
+ //#region src/core/logitron-logger.ts
211
+ var LogixiaLogger = class LogixiaLogger {
212
+ constructor(config, context) {
213
+ this.timers = /* @__PURE__ */ new Map();
214
+ this.contextData = {};
215
+ this.config = {
216
+ appName: "App",
217
+ environment: "development",
218
+ traceId: true,
219
+ format: {
220
+ timestamp: true,
221
+ colorize: true,
222
+ json: false
223
+ },
224
+ silent: false,
225
+ levelOptions: {
226
+ level: LogLevel.INFO,
227
+ levels: {
228
+ [LogLevel.ERROR]: 0,
229
+ [LogLevel.WARN]: 1,
230
+ [LogLevel.INFO]: 2,
231
+ [LogLevel.DEBUG]: 3,
232
+ [LogLevel.TRACE]: 4,
233
+ [LogLevel.VERBOSE]: 5
234
+ },
235
+ colors: {
236
+ [LogLevel.ERROR]: "red",
237
+ [LogLevel.WARN]: "yellow",
238
+ [LogLevel.INFO]: "blue",
239
+ [LogLevel.DEBUG]: "green",
240
+ [LogLevel.TRACE]: "gray",
241
+ [LogLevel.VERBOSE]: "cyan"
242
+ }
243
+ },
244
+ ...config
245
+ };
246
+ if (!this.config.fields) this.config.fields = {
247
+ timestamp: "[yyyy-mm-dd HH:MM:ss.MS]",
248
+ level: "[log_level]",
249
+ appName: "[app_name]",
250
+ traceId: "[trace_id]",
251
+ message: "[message]",
252
+ payload: "[payload]",
253
+ timeTaken: "[time_taken_MS]"
254
+ };
255
+ this.context = context ?? "";
256
+ this.createCustomLevelMethods();
257
+ }
258
+ /**
259
+ * Create dynamic methods for custom levels
260
+ */
261
+ createCustomLevelMethods() {
262
+ var _this$config$levelOpt;
263
+ if ((_this$config$levelOpt = this.config.levelOptions) === null || _this$config$levelOpt === void 0 ? void 0 : _this$config$levelOpt.levels) Object.keys(this.config.levelOptions.levels).forEach((levelName) => {
264
+ if (!this[levelName.toLowerCase()]) this[levelName.toLowerCase()] = async (message, data) => {
265
+ await this.log(levelName.toLowerCase(), message, data);
266
+ };
267
+ });
268
+ }
269
+ /**
270
+ * Error logging with overloads
271
+ */
272
+ async error(messageOrError, data) {
273
+ if (isError(messageOrError)) await this.log("error", messageOrError.message, {
274
+ ...data,
275
+ error: serializeError(messageOrError)
276
+ });
277
+ else await this.log("error", messageOrError, data);
278
+ }
279
+ async warn(message, data) {
280
+ await this.log("warn", message, data);
281
+ }
282
+ async info(message, data) {
283
+ await this.log("info", message, data);
284
+ }
285
+ async debug(message, data) {
286
+ await this.log("debug", message, data);
287
+ }
288
+ async trace(message, data) {
289
+ await this.log("trace", message, data);
290
+ }
291
+ async verbose(message, data) {
292
+ await this.log("verbose", message, data);
293
+ }
294
+ /**
295
+ * Log with custom level
296
+ */
297
+ async logLevel(level, message, data) {
298
+ await this.log(level, message, data);
299
+ }
300
+ /**
301
+ * Timing methods
302
+ */
303
+ time(label) {
304
+ this.timers.set(label, {
305
+ label,
306
+ startTime: Date.now()
307
+ });
308
+ }
309
+ async timeEnd(label) {
310
+ const timer = this.timers.get(label);
311
+ if (!timer) {
312
+ await this.warn(`Timer '${label}' does not exist`);
313
+ return;
314
+ }
315
+ const endTime = Date.now();
316
+ const duration = endTime - timer.startTime;
317
+ timer.endTime = endTime;
318
+ timer.duration = duration;
319
+ await this.info(`Timer '${label}' finished`, {
320
+ duration: `${duration}ms`,
321
+ startTime: new Date(timer.startTime).toISOString(),
322
+ endTime: new Date(endTime).toISOString()
323
+ });
324
+ this.timers.delete(label);
325
+ return duration;
326
+ }
327
+ async timeAsync(label, fn) {
328
+ this.time(label);
329
+ try {
330
+ const result = await fn();
331
+ await this.timeEnd(label);
332
+ return result;
333
+ } catch (error) {
334
+ await this.timeEnd(label);
335
+ throw error;
336
+ }
337
+ }
338
+ /**
339
+ * Level and context management
340
+ */
341
+ setLevel(level) {
342
+ this.config.levelOptions = this.config.levelOptions || {};
343
+ this.config.levelOptions.level = level;
344
+ }
345
+ getLevel() {
346
+ var _this$config$levelOpt2;
347
+ return ((_this$config$levelOpt2 = this.config.levelOptions) === null || _this$config$levelOpt2 === void 0 ? void 0 : _this$config$levelOpt2.level) || LogLevel.INFO;
348
+ }
349
+ setContext(context) {
350
+ this.context = context;
351
+ }
352
+ getContext() {
353
+ return this.context;
354
+ }
355
+ /**
356
+ * Create child logger
357
+ */
358
+ child(context, data) {
359
+ const childLogger = new LogixiaLogger(this.config, context);
360
+ if (data) childLogger.contextData = {
361
+ ...this.contextData,
362
+ ...data
363
+ };
364
+ return childLogger;
365
+ }
366
+ /**
367
+ * Close logger and cleanup resources
368
+ */
369
+ async close() {
370
+ for (const [label, timer] of this.timers) await this.warn(`Timer '${label}' was not ended properly`, {
371
+ startTime: new Date(timer.startTime).toISOString(),
372
+ duration: `${Date.now() - timer.startTime}ms (incomplete)`
373
+ });
374
+ this.timers.clear();
375
+ }
376
+ /**
377
+ * Core logging method
378
+ */
379
+ async log(level, message, data) {
380
+ if (this.config.silent) return;
381
+ if (!this.shouldLog(level)) return;
382
+ const entry = {
383
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
384
+ level,
385
+ appName: this.config.appName ?? "App",
386
+ message,
387
+ ...this.context && { context: this.context },
388
+ payload: {
389
+ ...this.contextData,
390
+ ...data
391
+ }
392
+ };
393
+ if (this.config.traceId) entry.traceId = getCurrentTraceId() || generateTraceId();
394
+ const formattedLog = this.formatLog(entry);
395
+ this.output(formattedLog, level);
396
+ }
397
+ /**
398
+ * Format log entry according to configuration
399
+ */
400
+ formatLog(entry) {
401
+ var _this$config$format, _this$config$format2, _this$config$format3, _this$config$levelOpt3;
402
+ if ((_this$config$format = this.config.format) === null || _this$config$format === void 0 ? void 0 : _this$config$format.json) return JSON.stringify(entry);
403
+ let formatted = "";
404
+ if (((_this$config$format2 = this.config.format) === null || _this$config$format2 === void 0 ? void 0 : _this$config$format2.timestamp) !== false) {
405
+ const timestamp = new Date(entry.timestamp).toLocaleString();
406
+ formatted += `[${timestamp}] `;
407
+ }
408
+ const levelName = entry.level;
409
+ const coloredLevel = ((_this$config$format3 = this.config.format) === null || _this$config$format3 === void 0 ? void 0 : _this$config$format3.colorize) ? this.colorize(levelName.toUpperCase(), ((_this$config$levelOpt3 = this.config.levelOptions) === null || _this$config$levelOpt3 === void 0 || (_this$config$levelOpt3 = _this$config$levelOpt3.colors) === null || _this$config$levelOpt3 === void 0 ? void 0 : _this$config$levelOpt3[levelName]) || "white") : levelName.toUpperCase();
410
+ formatted += `[${coloredLevel}] `;
411
+ formatted += `[${entry.appName}] `;
412
+ if (entry.traceId) formatted += `[${entry.traceId}] `;
413
+ if (entry.context) formatted += `[${entry.context}] `;
414
+ formatted += entry.message;
415
+ if (entry.payload && Object.keys(entry.payload).length > 0) formatted += ` ${JSON.stringify(entry.payload)}`;
416
+ return formatted;
417
+ }
418
+ /**
419
+ * Colorize text based on color name
420
+ */
421
+ colorize(text, color) {
422
+ var _this$config$format4;
423
+ if (!((_this$config$format4 = this.config.format) === null || _this$config$format4 === void 0 ? void 0 : _this$config$format4.colorize)) return text;
424
+ const colors = {
425
+ red: "\x1B[31m",
426
+ green: "\x1B[32m",
427
+ yellow: "\x1B[33m",
428
+ blue: "\x1B[34m",
429
+ magenta: "\x1B[35m",
430
+ cyan: "\x1B[36m",
431
+ white: "\x1B[37m",
432
+ gray: "\x1B[90m",
433
+ reset: "\x1B[0m"
434
+ };
435
+ return `${colors[color.toLowerCase()] || colors.white}${text}${colors.reset}`;
436
+ }
437
+ shouldLog(level) {
438
+ var _this$config$levelOpt4;
439
+ const currentLevel = this.getLevel();
440
+ const levelMap = {
441
+ [LogLevel.ERROR]: 0,
442
+ [LogLevel.WARN]: 1,
443
+ [LogLevel.INFO]: 2,
444
+ [LogLevel.DEBUG]: 3,
445
+ [LogLevel.TRACE]: 4,
446
+ [LogLevel.VERBOSE]: 5,
447
+ ...((_this$config$levelOpt4 = this.config.levelOptions) === null || _this$config$levelOpt4 === void 0 ? void 0 : _this$config$levelOpt4.levels) || {}
448
+ };
449
+ const currentLevelValue = levelMap[currentLevel];
450
+ const messageLevelValue = levelMap[level];
451
+ return messageLevelValue !== void 0 && currentLevelValue !== void 0 && messageLevelValue <= currentLevelValue;
452
+ }
453
+ /**
454
+ * Output log to console or other destinations
455
+ */
456
+ output(message, level) {
457
+ switch (level) {
458
+ case LogLevel.ERROR:
459
+ console.error(message);
460
+ break;
461
+ case LogLevel.WARN:
462
+ console.warn(message);
463
+ break;
464
+ case LogLevel.DEBUG:
465
+ case LogLevel.TRACE:
466
+ console.debug(message);
467
+ break;
468
+ default: console.log(message);
469
+ }
470
+ }
471
+ };
472
+ /**
473
+ * Factory function to create a typed logger with custom levels
474
+ */
475
+ function createLogger$1(config, context) {
476
+ var _config$levelOptions;
477
+ const logger$1 = new LogixiaLogger(config, context);
478
+ if ((_config$levelOptions = config.levelOptions) === null || _config$levelOptions === void 0 ? void 0 : _config$levelOptions.levels) Object.keys(config.levelOptions.levels).forEach((levelName) => {
479
+ if (!logger$1[levelName]) logger$1[levelName] = async (message, data) => {
480
+ await logger$1.log(levelName, message, data);
481
+ };
482
+ });
483
+ return logger$1;
484
+ }
485
+
486
+ //#endregion
487
+ //#region node_modules/.pnpm/@oxc-project+runtime@0.87.0/node_modules/@oxc-project/runtime/src/helpers/decorateMetadata.js
488
+ var require_decorateMetadata = /* @__PURE__ */ __commonJS({ "node_modules/.pnpm/@oxc-project+runtime@0.87.0/node_modules/@oxc-project/runtime/src/helpers/decorateMetadata.js": ((exports, module) => {
489
+ function __decorateMetadata(k, v) {
490
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
491
+ }
492
+ module.exports = __decorateMetadata, module.exports.__esModule = true, module.exports["default"] = module.exports;
493
+ }) });
494
+
495
+ //#endregion
496
+ //#region node_modules/.pnpm/@oxc-project+runtime@0.87.0/node_modules/@oxc-project/runtime/src/helpers/decorate.js
497
+ var require_decorate = /* @__PURE__ */ __commonJS({ "node_modules/.pnpm/@oxc-project+runtime@0.87.0/node_modules/@oxc-project/runtime/src/helpers/decorate.js": ((exports, module) => {
498
+ function __decorate(decorators, target, key, desc) {
499
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
500
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
501
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
502
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
503
+ }
504
+ module.exports = __decorate, module.exports.__esModule = true, module.exports["default"] = module.exports;
505
+ }) });
506
+
507
+ //#endregion
508
+ //#region src/core/logitron-nestjs.service.ts
509
+ var import_decorateMetadata$1 = /* @__PURE__ */ __toESM(require_decorateMetadata());
510
+ var import_decorate$2 = /* @__PURE__ */ __toESM(require_decorate());
511
+ var _LogixiaLoggerService;
512
+ let LogixiaLoggerService = _LogixiaLoggerService = class LogixiaLoggerService$1 {
513
+ constructor(config) {
514
+ const defaultConfig = {
515
+ appName: "NestJS-App",
516
+ environment: "development",
517
+ traceId: true,
518
+ format: {
519
+ timestamp: true,
520
+ colorize: true,
521
+ json: false
522
+ },
523
+ silent: false,
524
+ levelOptions: {
525
+ level: LogLevel.INFO,
526
+ levels: {
527
+ error: 0,
528
+ warn: 1,
529
+ log: 2,
530
+ debug: 3,
531
+ verbose: 4
532
+ },
533
+ colors: {
534
+ error: "red",
535
+ warn: "yellow",
536
+ log: "green",
537
+ debug: "blue",
538
+ verbose: "cyan"
539
+ }
540
+ },
541
+ fields: {
542
+ timestamp: "[yyyy-mm-dd HH:MM:ss.MS]",
543
+ level: "[log_level]",
544
+ appName: "[app_name]",
545
+ traceId: "[trace_id]",
546
+ message: "[message]",
547
+ payload: "[payload]",
548
+ timeTaken: "[time_taken_MS]"
549
+ }
550
+ };
551
+ this.logger = new LogixiaLogger({
552
+ ...defaultConfig,
553
+ ...config
554
+ });
555
+ }
556
+ /**
557
+ * NestJS LoggerService interface implementation
558
+ */
559
+ log(message, context) {
560
+ this.setContextIfProvided(context);
561
+ this.logger.info(this.formatMessage(message)).catch(console.error);
562
+ }
563
+ error(message, trace, context) {
564
+ this.setContextIfProvided(context);
565
+ const errorData = {};
566
+ if (trace) errorData.stack = trace;
567
+ if (typeof message === "object" && message instanceof Error) this.logger.error(message, errorData).catch(console.error);
568
+ else this.logger.error(this.formatMessage(message), errorData).catch(console.error);
569
+ }
570
+ warn(message, context) {
571
+ this.setContextIfProvided(context);
572
+ this.logger.warn(this.formatMessage(message)).catch(console.error);
573
+ }
574
+ debug(message, context) {
575
+ this.setContextIfProvided(context);
576
+ this.logger.debug(this.formatMessage(message)).catch(console.error);
577
+ }
578
+ verbose(message, context) {
579
+ this.setContextIfProvided(context);
580
+ this.logger.trace(this.formatMessage(message)).catch(console.error);
581
+ }
582
+ /**
583
+ * Extended Logitron methods
584
+ */
585
+ async info(message, data) {
586
+ return this.logger.info(message, data);
587
+ }
588
+ async trace(message, data) {
589
+ return this.logger.trace(message, data);
590
+ }
591
+ logLevel(level, message, data) {
592
+ return this.logger.logLevel(level, message, data);
593
+ }
594
+ /**
595
+ * Timing methods
596
+ */
597
+ time(label) {
598
+ this.logger.time(label);
599
+ }
600
+ async timeEnd(label) {
601
+ return this.logger.timeEnd(label);
602
+ }
603
+ async timeAsync(label, fn) {
604
+ return this.logger.timeAsync(label, fn);
605
+ }
606
+ /**
607
+ * Context and level management
608
+ */
609
+ setContext(context) {
610
+ this.context = context;
611
+ this.logger.setContext(context);
612
+ }
613
+ getContext() {
614
+ return this.context;
615
+ }
616
+ setLevel(level) {
617
+ this.logger.setLevel(level);
618
+ }
619
+ getLevel() {
620
+ return this.logger.getLevel();
621
+ }
622
+ /**
623
+ * Create child logger
624
+ */
625
+ child(context, data) {
626
+ const childService = new _LogixiaLoggerService();
627
+ childService.logger = this.logger.child(context, data);
628
+ childService.context = context;
629
+ return childService;
630
+ }
631
+ /**
632
+ * Get current trace ID
633
+ */
634
+ getCurrentTraceId() {
635
+ return getCurrentTraceId();
636
+ }
637
+ /**
638
+ * Close logger
639
+ */
640
+ async close() {
641
+ return this.logger.close();
642
+ }
643
+ /**
644
+ * Private helper methods
645
+ */
646
+ setContextIfProvided(context) {
647
+ if (context && context !== this.context) this.setContext(context);
648
+ }
649
+ formatMessage(message) {
650
+ if (typeof message === "string") return message;
651
+ if (typeof message === "object") return JSON.stringify(message);
652
+ return String(message);
653
+ }
654
+ /**
655
+ * Static factory method for easy instantiation
656
+ */
657
+ static create(config) {
658
+ return new _LogixiaLoggerService(config);
659
+ }
660
+ /**
661
+ * Get the underlying Logitron logger instance
662
+ */
663
+ getLogger() {
664
+ return this.logger;
665
+ }
666
+ };
667
+ LogixiaLoggerService = _LogixiaLoggerService = (0, import_decorate$2.default)([(0, __nestjs_common.Injectable)({ scope: __nestjs_common.Scope.TRANSIENT }), (0, import_decorateMetadata$1.default)("design:paramtypes", [Object])], LogixiaLoggerService);
668
+
669
+ //#endregion
670
+ //#region src/core/trace.middleware.ts
671
+ var import_decorateMetadata = /* @__PURE__ */ __toESM(require_decorateMetadata());
672
+ var import_decorate$1 = /* @__PURE__ */ __toESM(require_decorate());
673
+ let TraceMiddleware = class TraceMiddleware$1 {
674
+ constructor(config) {
675
+ this.config = config;
676
+ this.config = {
677
+ enabled: true,
678
+ generator: generateTraceId,
679
+ contextKey: "traceId",
680
+ extractor: {
681
+ header: [
682
+ "x-trace-id",
683
+ "x-request-id",
684
+ "trace-id"
685
+ ],
686
+ query: ["traceId", "trace_id"]
687
+ },
688
+ ...config
689
+ };
690
+ }
691
+ use(req, res, next) {
692
+ var _this$config;
693
+ if (!((_this$config = this.config) === null || _this$config === void 0 ? void 0 : _this$config.enabled)) return next();
694
+ let traceId;
695
+ if (this.config.extractor) traceId = extractTraceId(req, this.config.extractor);
696
+ if (!traceId) traceId = this.config.generator ? this.config.generator() : generateTraceId();
697
+ req.traceId = traceId;
698
+ req.requestId = req.requestId || generateTraceId();
699
+ res.setHeader("X-Trace-Id", traceId);
700
+ res.setHeader("X-Request-Id", req.requestId);
701
+ runWithTraceId(traceId, () => {
702
+ next();
703
+ }, {
704
+ requestId: req.requestId,
705
+ method: req.method,
706
+ url: req.url,
707
+ userAgent: req.get("User-Agent"),
708
+ ip: req.ip || req.connection.remoteAddress
709
+ });
710
+ }
711
+ };
712
+ TraceMiddleware = (0, import_decorate$1.default)([(0, __nestjs_common.Injectable)(), (0, import_decorateMetadata.default)("design:paramtypes", [Object])], TraceMiddleware);
713
+
714
+ //#endregion
715
+ //#region src/core/logitron-logger.module.ts
716
+ var import_decorate = /* @__PURE__ */ __toESM(require_decorate());
717
+ var _LogixiaLoggerModule;
718
+ const DEFAULT_ROUTES = [{
719
+ path: "*",
720
+ method: __nestjs_common.RequestMethod.ALL
721
+ }];
722
+ const LOGIXIA_LOGGER_CONFIG = "LOGIXIA_LOGGER_CONFIG";
723
+ const LOGIXIA_LOGGER_PREFIX = "LOGIXIA_LOGGER_";
724
+ let LogixiaLoggerModule = class LogixiaLoggerModule$1 {
725
+ static {
726
+ _LogixiaLoggerModule = this;
727
+ }
728
+ constructor() {
729
+ this.config = {};
730
+ }
731
+ static #_ = this.loggerConfig = {};
732
+ configure(consumer) {
733
+ const { forRoutes = DEFAULT_ROUTES, exclude } = this.config;
734
+ const middlewareConfig = (req, res, next) => {
735
+ let traceConfig;
736
+ if (typeof _LogixiaLoggerModule.loggerConfig.traceId === "object") traceConfig = _LogixiaLoggerModule.loggerConfig.traceId;
737
+ else if (_LogixiaLoggerModule.loggerConfig.traceId === true) traceConfig = {
738
+ enabled: true,
739
+ contextKey: "traceId",
740
+ generator: () => {
741
+ const timestamp = Date.now().toString(36);
742
+ const random = Math.random().toString(36).substring(2, 8);
743
+ return `${timestamp}-${random}`;
744
+ }
745
+ };
746
+ else traceConfig = void 0;
747
+ return new TraceMiddleware(traceConfig).use(req, res, next);
748
+ };
749
+ if (exclude) consumer.apply(middlewareConfig).exclude(...exclude).forRoutes(...forRoutes);
750
+ else consumer.apply(middlewareConfig).forRoutes(...forRoutes);
751
+ }
752
+ /**
753
+ * Configure the module with synchronous options
754
+ */
755
+ static forRoot(config) {
756
+ _LogixiaLoggerModule.loggerConfig = config || {};
757
+ return {
758
+ module: _LogixiaLoggerModule,
759
+ providers: [{
760
+ provide: LOGIXIA_LOGGER_CONFIG,
761
+ useValue: config || {}
762
+ }, {
763
+ provide: LogixiaLoggerService,
764
+ useFactory: (loggerConfig) => {
765
+ const defaultConfig = {
766
+ level: "info",
767
+ service: "NestJSApp",
768
+ environment: "development",
769
+ fields: {},
770
+ formatters: ["text"],
771
+ outputs: ["console"],
772
+ levelOptions: {
773
+ level: "info",
774
+ levels: {
775
+ error: 0,
776
+ warn: 1,
777
+ info: 2,
778
+ debug: 3,
779
+ verbose: 4
780
+ },
781
+ colors: {
782
+ error: "red",
783
+ warn: "yellow",
784
+ info: "green",
785
+ debug: "blue",
786
+ verbose: "cyan"
787
+ }
788
+ },
789
+ ...loggerConfig
790
+ };
791
+ return new LogixiaLoggerService(defaultConfig);
792
+ },
793
+ inject: [LOGIXIA_LOGGER_CONFIG]
794
+ }],
795
+ exports: [LogixiaLoggerService, LOGIXIA_LOGGER_CONFIG],
796
+ global: true
797
+ };
798
+ }
799
+ /**
800
+ * Configure the module with asynchronous options
801
+ */
802
+ static forRootAsync(options) {
803
+ return {
804
+ module: _LogixiaLoggerModule,
805
+ imports: options.imports || [],
806
+ providers: [...this.createAsyncProviders(options), {
807
+ provide: LogixiaLoggerService,
808
+ useFactory: (loggerConfig) => {
809
+ const defaultConfig = {
810
+ level: "info",
811
+ service: "NestJSApp",
812
+ environment: "development",
813
+ fields: {},
814
+ formatters: ["text"],
815
+ outputs: ["console"],
816
+ levelOptions: {
817
+ level: "info",
818
+ levels: {
819
+ error: 0,
820
+ warn: 1,
821
+ info: 2,
822
+ debug: 3,
823
+ verbose: 4
824
+ },
825
+ colors: {
826
+ error: "red",
827
+ warn: "yellow",
828
+ info: "green",
829
+ debug: "blue",
830
+ verbose: "cyan"
831
+ }
832
+ },
833
+ ...loggerConfig
834
+ };
835
+ _LogixiaLoggerModule.loggerConfig = defaultConfig;
836
+ return new LogixiaLoggerService(defaultConfig);
837
+ },
838
+ inject: [LOGIXIA_LOGGER_CONFIG]
839
+ }],
840
+ exports: [LogixiaLoggerService, LOGIXIA_LOGGER_CONFIG],
841
+ global: true
842
+ };
843
+ }
844
+ /**
845
+ * Create feature-specific logger instances
846
+ */
847
+ static forFeature(context) {
848
+ const providerToken = `${LOGIXIA_LOGGER_PREFIX}${context.toUpperCase()}`;
849
+ return {
850
+ module: _LogixiaLoggerModule,
851
+ providers: [{
852
+ provide: providerToken,
853
+ useFactory: (baseLogger) => {
854
+ return baseLogger.child(context);
855
+ },
856
+ inject: [LogixiaLoggerService]
857
+ }],
858
+ exports: [providerToken]
859
+ };
860
+ }
861
+ static createAsyncProviders(options) {
862
+ if (options.useExisting || options.useFactory) return [this.createAsyncOptionsProvider(options)];
863
+ return [this.createAsyncOptionsProvider(options), {
864
+ provide: options.useClass,
865
+ useClass: options.useClass
866
+ }];
867
+ }
868
+ static createAsyncOptionsProvider(options) {
869
+ if (options.useFactory) return {
870
+ provide: LOGIXIA_LOGGER_CONFIG,
871
+ useFactory: options.useFactory,
872
+ inject: options.inject || []
873
+ };
874
+ return {
875
+ provide: LOGIXIA_LOGGER_CONFIG,
876
+ useFactory: async (optionsFactory) => await optionsFactory.createLogixiaOptions(),
877
+ inject: [options.useExisting || options.useClass]
878
+ };
879
+ }
880
+ };
881
+ LogixiaLoggerModule = _LogixiaLoggerModule = (0, import_decorate.default)([(0, __nestjs_common.Module)({})], LogixiaLoggerModule);
882
+
883
+ //#endregion
884
+ //#region src/formatters/json.formatter.ts
885
+ var JsonFormatter = class {
886
+ constructor(options = {}) {
887
+ this.includeTimestamp = options.includeTimestamp ?? true;
888
+ this.includeLevel = options.includeLevel ?? true;
889
+ this.includeAppName = options.includeAppName ?? true;
890
+ this.includeTraceId = options.includeTraceId ?? true;
891
+ this.includeContext = options.includeContext ?? true;
892
+ this.prettyPrint = options.prettyPrint ?? false;
893
+ }
894
+ format(entry) {
895
+ const formatted = {};
896
+ if (this.includeTimestamp) formatted.timestamp = entry.timestamp;
897
+ if (this.includeLevel) {
898
+ formatted.level = entry.level.toLowerCase();
899
+ formatted.levelValue = entry.level;
900
+ }
901
+ if (this.includeAppName) formatted.appName = entry.appName;
902
+ if (this.includeTraceId && entry.traceId) formatted.traceId = entry.traceId;
903
+ if (this.includeContext && entry.context) formatted.context = entry.context;
904
+ formatted.message = entry.message;
905
+ if (entry.payload && Object.keys(entry.payload).length > 0) formatted.payload = this.serializePayload(entry.payload);
906
+ if (entry.error) formatted.error = serializeError(entry.error);
907
+ formatted.meta = {
908
+ pid: process.pid,
909
+ hostname: process.env.HOSTNAME || "unknown",
910
+ version: process.version
911
+ };
912
+ return this.prettyPrint ? JSON.stringify(formatted, null, 2) : JSON.stringify(formatted);
913
+ }
914
+ serializePayload(payload) {
915
+ const serialized = {};
916
+ for (const [key, value] of Object.entries(payload)) try {
917
+ if (value instanceof Error) serialized[key] = serializeError(value);
918
+ else if (value instanceof Date) serialized[key] = value.toISOString();
919
+ else if (typeof value === "function") serialized[key] = "[Function]";
920
+ else if (typeof value === "symbol") serialized[key] = value.toString();
921
+ else if (value === void 0) serialized[key] = null;
922
+ else serialized[key] = value;
923
+ } catch {
924
+ serialized[key] = "[Unserializable]";
925
+ }
926
+ return serialized;
927
+ }
928
+ };
929
+
930
+ //#endregion
931
+ //#region src/formatters/text.formatter.ts
932
+ var TextFormatter = class TextFormatter {
933
+ constructor(options = {}) {
934
+ this.colorize = options.colorize ?? true;
935
+ this.includeTimestamp = options.includeTimestamp ?? true;
936
+ this.includeAppName = options.includeAppName ?? true;
937
+ this.includeTraceId = options.includeTraceId ?? true;
938
+ this.includeContext = options.includeContext ?? true;
939
+ this.timestampFormat = options.timestampFormat ?? "locale";
940
+ this.colors = {
941
+ error: "\x1B[31m",
942
+ warn: "\x1B[33m",
943
+ info: "\x1B[32m",
944
+ debug: "\x1B[34m",
945
+ trace: "\x1B[35m",
946
+ verbose: "\x1B[36m",
947
+ reset: "\x1B[0m",
948
+ bold: "\x1B[1m",
949
+ dim: "\x1B[2m",
950
+ ...options.colors
951
+ };
952
+ }
953
+ format(entry) {
954
+ const parts = [];
955
+ if (this.includeTimestamp) {
956
+ const timestamp = this.formatTimestamp(entry.timestamp);
957
+ parts.push(this.colorize ? `${this.colors.dim}${timestamp}${this.colors.reset}` : timestamp);
958
+ }
959
+ const levelName = entry.level.toLowerCase();
960
+ const levelColor = this.colors[levelName] || this.colors.reset;
961
+ const formattedLevel = this.colorize ? `${levelColor}${this.colors.bold}${levelName.toUpperCase().padEnd(5)}${this.colors.reset}` : levelName.toUpperCase().padEnd(5);
962
+ parts.push(`[${formattedLevel}]`);
963
+ if (this.includeAppName) {
964
+ const appName = this.colorize ? `${this.colors.bold}${entry.appName}${this.colors.reset}` : entry.appName;
965
+ parts.push(`[${appName}]`);
966
+ }
967
+ if (this.includeTraceId && entry.traceId) {
968
+ const traceId = this.colorize ? `${this.colors.dim}${entry.traceId}${this.colors.reset}` : entry.traceId;
969
+ parts.push(`[${traceId}]`);
970
+ }
971
+ if (this.includeContext && entry.context) {
972
+ const context = this.colorize ? `${this.colors.cyan}${entry.context}${this.colors.reset}` : entry.context;
973
+ parts.push(`[${context}]`);
974
+ }
975
+ const message = this.colorize && entry.level === LogLevel.ERROR ? `${this.colors.error}${entry.message}${this.colors.reset}` : entry.message;
976
+ parts.push(message);
977
+ if (entry.payload && Object.keys(entry.payload).length > 0) {
978
+ const payload = this.formatPayload(entry.payload);
979
+ if (payload) parts.push(this.colorize ? `${this.colors.dim}${payload}${this.colors.reset}` : payload);
980
+ }
981
+ return parts.join(" ");
982
+ }
983
+ formatTimestamp(timestamp) {
984
+ const date = new Date(timestamp);
985
+ switch (this.timestampFormat) {
986
+ case "iso": return date.toISOString();
987
+ case "short": return date.toLocaleTimeString();
988
+ case "locale":
989
+ default: return date.toLocaleString();
990
+ }
991
+ }
992
+ formatPayload(payload) {
993
+ try {
994
+ if (Object.keys(payload).length === 1) {
995
+ const entry = Object.entries(payload)[0];
996
+ if (entry) {
997
+ const [key, value] = entry;
998
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return `${key}=${value}`;
999
+ }
1000
+ }
1001
+ return Object.entries(payload).map(([key, value]) => {
1002
+ if (value === null || value === void 0) return `${key}=${value}`;
1003
+ if (typeof value === "string") return `${key}="${value}"`;
1004
+ if (typeof value === "number" || typeof value === "boolean") return `${key}=${value}`;
1005
+ if (value instanceof Date) return `${key}=${value.toISOString()}`;
1006
+ if (typeof value === "object") return `${key}=${JSON.stringify(value)}`;
1007
+ return `${key}=${String(value)}`;
1008
+ }).join(" ");
1009
+ } catch {
1010
+ return JSON.stringify(payload);
1011
+ }
1012
+ }
1013
+ /**
1014
+ * Create a formatter with preset configurations
1015
+ */
1016
+ static createSimple() {
1017
+ return new TextFormatter({
1018
+ colorize: true,
1019
+ includeTimestamp: true,
1020
+ includeAppName: false,
1021
+ includeTraceId: false,
1022
+ includeContext: true,
1023
+ timestampFormat: "short"
1024
+ });
1025
+ }
1026
+ static createDetailed() {
1027
+ return new TextFormatter({
1028
+ colorize: true,
1029
+ includeTimestamp: true,
1030
+ includeAppName: true,
1031
+ includeTraceId: true,
1032
+ includeContext: true,
1033
+ timestampFormat: "locale"
1034
+ });
1035
+ }
1036
+ static createMinimal() {
1037
+ return new TextFormatter({
1038
+ colorize: false,
1039
+ includeTimestamp: false,
1040
+ includeAppName: false,
1041
+ includeTraceId: false,
1042
+ includeContext: false
1043
+ });
1044
+ }
1045
+ };
1046
+
1047
+ //#endregion
1048
+ //#region src/index.ts
1049
+ /**
1050
+ * Default configuration for Logitron logger
1051
+ */
1052
+ const DEFAULT_CONFIG = {
1053
+ appName: "App",
1054
+ environment: "development",
1055
+ traceId: true,
1056
+ format: {
1057
+ timestamp: true,
1058
+ colorize: true,
1059
+ json: false
1060
+ },
1061
+ silent: false,
1062
+ levelOptions: {
1063
+ level: LogLevel.INFO,
1064
+ levels: {
1065
+ [LogLevel.ERROR]: 0,
1066
+ [LogLevel.WARN]: 1,
1067
+ [LogLevel.INFO]: 2,
1068
+ [LogLevel.DEBUG]: 3,
1069
+ [LogLevel.TRACE]: 4,
1070
+ [LogLevel.VERBOSE]: 5
1071
+ },
1072
+ colors: {
1073
+ [LogLevel.ERROR]: "red",
1074
+ [LogLevel.WARN]: "yellow",
1075
+ [LogLevel.INFO]: "blue",
1076
+ [LogLevel.DEBUG]: "green",
1077
+ [LogLevel.TRACE]: "gray",
1078
+ [LogLevel.VERBOSE]: "cyan"
1079
+ }
1080
+ },
1081
+ fields: {
1082
+ timestamp: true,
1083
+ level: true,
1084
+ appName: true,
1085
+ traceId: true,
1086
+ message: true,
1087
+ payload: true,
1088
+ timeTaken: true
1089
+ },
1090
+ outputs: ["console"]
1091
+ };
1092
+ /**
1093
+ * Create a new Logitron logger instance with TypeScript support for custom levels
1094
+ * @param config - Logger configuration
1095
+ * @returns Typed logger instance
1096
+ */
1097
+ const createLogger = createLogger$1;
1098
+ /**
1099
+ * Create a new Logitron logger service for NestJS
1100
+ * @param config - Logger configuration
1101
+ * @returns LogixiaLoggerService instance
1102
+ */
1103
+ function createLoggerService(config) {
1104
+ return new LogixiaLoggerService({
1105
+ ...DEFAULT_CONFIG,
1106
+ ...config
1107
+ });
1108
+ }
1109
+ /**
1110
+ * Default logger instance
1111
+ */
1112
+ const logger = new LogixiaLogger(DEFAULT_CONFIG);
1113
+ /**
1114
+ * Export default configuration for reference
1115
+ */
1116
+ //#endregion
1117
+ exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
1118
+ exports.DEFAULT_LOG_COLORS = DEFAULT_LOG_COLORS;
1119
+ exports.DEFAULT_LOG_LEVELS = DEFAULT_LOG_LEVELS;
1120
+ exports.JsonFormatter = JsonFormatter;
1121
+ exports.LOGIXIA_LOGGER_CONFIG = LOGIXIA_LOGGER_CONFIG;
1122
+ exports.LOGIXIA_LOGGER_PREFIX = LOGIXIA_LOGGER_PREFIX;
1123
+ exports.LogLevel = LogLevel;
1124
+ exports.LogixiaLogger = LogixiaLogger;
1125
+ Object.defineProperty(exports, 'LogixiaLoggerModule', {
1126
+ enumerable: true,
1127
+ get: function () {
1128
+ return LogixiaLoggerModule;
1129
+ }
1130
+ });
1131
+ Object.defineProperty(exports, 'LogixiaLoggerService', {
1132
+ enumerable: true,
1133
+ get: function () {
1134
+ return LogixiaLoggerService;
1135
+ }
1136
+ });
1137
+ exports.TextFormatter = TextFormatter;
1138
+ exports.createLogger = createLogger;
1139
+ exports.createLoggerService = createLoggerService;
1140
+ exports.createTraceMiddleware = createTraceMiddleware;
1141
+ exports.extractTraceId = extractTraceId;
1142
+ exports.generateTraceId = generateTraceId;
1143
+ exports.getCurrentTraceId = getCurrentTraceId;
1144
+ exports.isError = isError;
1145
+ exports.logger = logger;
1146
+ exports.normalizeError = normalizeError;
1147
+ exports.runWithTraceId = runWithTraceId;
1148
+ exports.serializeError = serializeError;
1149
+ exports.setTraceId = setTraceId;
1150
+ exports.traceStorage = traceStorage;
1151
+ //# sourceMappingURL=index.js.map