@pencroff-lab/kore 0.1.2 → 0.2.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/README.md CHANGED
@@ -19,6 +19,8 @@ Detailed API documentation for each module:
19
19
  - [Err](docs/err.md) -- Immutable, value-based error type with wrapping, aggregation, and serialization
20
20
  - [Outcome\<T\>](docs/outcome.md) -- Monadic container for type-safe error handling with tuple-first API
21
21
  - [dtStamp](docs/format_dt.md) -- Filesystem/log-safe date formatting utility
22
+ - [Logger](docs/logger.md) -- Structured logging with transport DI and Err integration
23
+ - [Logging Guide](docs/logging_guide.md) -- Patterns, conventions, and integration strategies
22
24
 
23
25
  ## API
24
26
 
@@ -209,10 +211,39 @@ import { dtStamp } from "@pencroff-lab/kore";
209
211
  dtStamp(); // "20260218_153045"
210
212
  dtStamp(new Date(), { parts: "date" }); // "20260218"
211
213
  dtStamp(new Date(), { parts: "time", ms: true }); // "153045_123"
212
- dtStamp(new Date(), { compact: true }); // "20260218153045"
214
+ dtStamp(new Date(), { readable: true }); // "2026-02-18_15:30:45"
213
215
  dtStamp(new Date(), { tz: "local" }); // uses local timezone
214
216
  ```
215
217
 
218
+ #### Logger
219
+
220
+ Structured, callable logger with transport DI, child loggers, and automatic `Err` formatting.
221
+
222
+ ```typescript
223
+ import { log, createLogger } from "@pencroff-lab/kore";
224
+
225
+ // Default logger
226
+ log("Application started");
227
+ log(log.WARN, "Connection slow");
228
+ log(log.ERROR, "Failed to save", { userId: "123" });
229
+
230
+ // Module-specific logger
231
+ const dbLog = createLogger("database");
232
+ dbLog("Connected to postgres");
233
+
234
+ // Child loggers with inherited context
235
+ const userLog = dbLog.child("users", { version: "1.0" });
236
+ userLog("User created");
237
+ // Output: [database] [users] User created {"version":"1.0"}
238
+
239
+ // Err instances rendered automatically
240
+ const [data, err] = fetchData();
241
+ if (err) {
242
+ log(log.ERROR, "Fetch failed", err);
243
+ // Output includes indented Err.toString() below the log line
244
+ }
245
+ ```
246
+
216
247
  ## Development
217
248
 
218
249
  ```bash
@@ -4,7 +4,6 @@
4
4
  export interface DtStampOptions {
5
5
  /**
6
6
  * Character(s) between date/time segments.
7
- * Ignored when `compact` is `true`.
8
7
  * @default "_"
9
8
  */
10
9
  delimiter?: string;
@@ -23,16 +22,18 @@ export interface DtStampOptions {
23
22
  /**
24
23
  * Which parts of the stamp to include.
25
24
  * - `"datetime"` -- full stamp (date + time)
26
- * - `"date"` -- date only (`YYYYMMDD`)
27
- * - `"time"` -- time only (`HHmmss` or `HHmmss_SSS` with `ms`)
25
+ * - `"date"` -- date only
26
+ * - `"time"` -- time only
28
27
  * @default "datetime"
29
28
  */
30
29
  parts?: "datetime" | "date" | "time";
31
30
  /**
32
- * When `true`, omits the delimiter entirely (equivalent to `delimiter: ""`).
31
+ * When `true`, formats with human-readable separators:
32
+ * dashes in date (`YYYY-MM-DD`), colons in time (`HH:MM:SS`),
33
+ * and `.` before milliseconds in time-only mode (`HH:MM:SS.mmm`).
33
34
  * @default false
34
35
  */
35
- compact?: boolean;
36
+ readable?: boolean;
36
37
  }
37
38
  /**
38
39
  * Format a `Date` into a filesystem/log-safe timestamp string.
@@ -41,7 +42,7 @@ export interface DtStampOptions {
41
42
  * and anywhere a human-readable but machine-sortable date/time is needed.
42
43
  *
43
44
  * @param date - Date to format. Defaults to `new Date()` when `null` or omitted.
44
- * @param options - Formatting options (delimiter, milliseconds, timezone, parts, compact)
45
+ * @param options - Formatting options (delimiter, milliseconds, timezone, parts, readable)
45
46
  * @returns Formatted timestamp string
46
47
  *
47
48
  * @example Default (UTC datetime with underscore delimiter)
@@ -50,22 +51,22 @@ export interface DtStampOptions {
50
51
  * // "20240315_103045"
51
52
  * ```
52
53
  *
53
- * @example Compact with milliseconds
54
+ * @example Readable datetime with milliseconds
54
55
  * ```typescript
55
- * dtStamp(new Date("2024-03-15T10:30:45.123Z"), { compact: true, ms: true });
56
- * // "20240315103045123"
56
+ * dtStamp(new Date("2024-03-15T10:30:45.123Z"), { readable: true, ms: true });
57
+ * // "2024-03-15_10:30:45_123"
57
58
  * ```
58
59
  *
59
- * @example Date only
60
+ * @example Readable date only
60
61
  * ```typescript
61
- * dtStamp(new Date("2024-03-15T10:30:45.123Z"), { parts: "date" });
62
- * // "20240315"
62
+ * dtStamp(new Date("2024-03-15T10:30:45.123Z"), { readable: true, parts: "date" });
63
+ * // "2024-03-15"
63
64
  * ```
64
65
  *
65
- * @example Time only with milliseconds
66
+ * @example Readable time with milliseconds
66
67
  * ```typescript
67
- * dtStamp(new Date("2024-03-15T10:30:45.123Z"), { parts: "time", ms: true });
68
- * // "103045_123"
68
+ * dtStamp(new Date("2024-03-15T10:30:45.123Z"), { readable: true, parts: "time", ms: true });
69
+ * // "10:30:45.123"
69
70
  * ```
70
71
  *
71
72
  * @example Custom delimiter
@@ -1 +1 @@
1
- {"version":3,"file":"format_dt.d.ts","sourceRoot":"","sources":["../../../../src/utils/format_dt.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,EAAE,CAAC,EAAE,OAAO,CAAC;IACb;;;;;OAKG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;IACrC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,MAAM,CA8C5E"}
1
+ {"version":3,"file":"format_dt.d.ts","sourceRoot":"","sources":["../../../../src/utils/format_dt.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,EAAE,CAAC,EAAE,OAAO,CAAC;IACb;;;;;OAKG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,MAAM,CAkD5E"}
@@ -8,7 +8,7 @@ exports.dtStamp = dtStamp;
8
8
  * and anywhere a human-readable but machine-sortable date/time is needed.
9
9
  *
10
10
  * @param date - Date to format. Defaults to `new Date()` when `null` or omitted.
11
- * @param options - Formatting options (delimiter, milliseconds, timezone, parts, compact)
11
+ * @param options - Formatting options (delimiter, milliseconds, timezone, parts, readable)
12
12
  * @returns Formatted timestamp string
13
13
  *
14
14
  * @example Default (UTC datetime with underscore delimiter)
@@ -17,22 +17,22 @@ exports.dtStamp = dtStamp;
17
17
  * // "20240315_103045"
18
18
  * ```
19
19
  *
20
- * @example Compact with milliseconds
20
+ * @example Readable datetime with milliseconds
21
21
  * ```typescript
22
- * dtStamp(new Date("2024-03-15T10:30:45.123Z"), { compact: true, ms: true });
23
- * // "20240315103045123"
22
+ * dtStamp(new Date("2024-03-15T10:30:45.123Z"), { readable: true, ms: true });
23
+ * // "2024-03-15_10:30:45_123"
24
24
  * ```
25
25
  *
26
- * @example Date only
26
+ * @example Readable date only
27
27
  * ```typescript
28
- * dtStamp(new Date("2024-03-15T10:30:45.123Z"), { parts: "date" });
29
- * // "20240315"
28
+ * dtStamp(new Date("2024-03-15T10:30:45.123Z"), { readable: true, parts: "date" });
29
+ * // "2024-03-15"
30
30
  * ```
31
31
  *
32
- * @example Time only with milliseconds
32
+ * @example Readable time with milliseconds
33
33
  * ```typescript
34
- * dtStamp(new Date("2024-03-15T10:30:45.123Z"), { parts: "time", ms: true });
35
- * // "103045_123"
34
+ * dtStamp(new Date("2024-03-15T10:30:45.123Z"), { readable: true, parts: "time", ms: true });
35
+ * // "10:30:45.123"
36
36
  * ```
37
37
  *
38
38
  * @example Custom delimiter
@@ -43,8 +43,7 @@ exports.dtStamp = dtStamp;
43
43
  */
44
44
  function dtStamp(date, options) {
45
45
  const d = date ?? new Date();
46
- const { delimiter = "_", ms = false, tz = "utc", parts = "datetime", compact = false, } = options ?? {};
47
- const sep = compact ? "" : delimiter;
46
+ const { delimiter = "_", ms = false, tz = "utc", parts = "datetime", readable = false, } = options ?? {};
48
47
  const utc = tz === "utc";
49
48
  const year = utc ? d.getUTCFullYear() : d.getFullYear();
50
49
  const month = String((utc ? d.getUTCMonth() : d.getMonth()) + 1).padStart(2, "0");
@@ -52,11 +51,16 @@ function dtStamp(date, options) {
52
51
  const hours = String(utc ? d.getUTCHours() : d.getHours()).padStart(2, "0");
53
52
  const minutes = String(utc ? d.getUTCMinutes() : d.getMinutes()).padStart(2, "0");
54
53
  const seconds = String(utc ? d.getUTCSeconds() : d.getSeconds()).padStart(2, "0");
55
- const datePart = `${year}${month}${day}`;
56
- let timePart = `${hours}${minutes}${seconds}`;
54
+ const datePart = readable
55
+ ? `${year}-${month}-${day}`
56
+ : `${year}${month}${day}`;
57
+ let timePart = readable
58
+ ? `${hours}:${minutes}:${seconds}`
59
+ : `${hours}${minutes}${seconds}`;
57
60
  if (ms) {
58
61
  const millis = String(utc ? d.getUTCMilliseconds() : d.getMilliseconds()).padStart(3, "0");
59
- timePart = `${timePart}${sep}${millis}`;
62
+ const msSep = readable && parts === "time" ? "." : delimiter;
63
+ timePart = `${timePart}${msSep}${millis}`;
60
64
  }
61
65
  if (parts === "date") {
62
66
  return datePart;
@@ -64,6 +68,6 @@ function dtStamp(date, options) {
64
68
  if (parts === "time") {
65
69
  return timePart;
66
70
  }
67
- return `${datePart}${sep}${timePart}`;
71
+ return `${datePart}${delimiter}${timePart}`;
68
72
  }
69
73
  //# sourceMappingURL=format_dt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"format_dt.js","sourceRoot":"","sources":["../../../../src/utils/format_dt.ts"],"names":[],"mappings":";;AA6EA,0BA8CC;AAtFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,SAAgB,OAAO,CAAC,IAAkB,EAAE,OAAwB;IACnE,MAAM,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;IAC7B,MAAM,EACL,SAAS,GAAG,GAAG,EACf,EAAE,GAAG,KAAK,EACV,EAAE,GAAG,KAAK,EACV,KAAK,GAAG,UAAU,EAClB,OAAO,GAAG,KAAK,GACf,GAAG,OAAO,IAAI,EAAE,CAAC;IAElB,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACrC,MAAM,GAAG,GAAG,EAAE,KAAK,KAAK,CAAC;IAEzB,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CACxE,CAAC,EACD,GAAG,CACH,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CACxE,CAAC,EACD,GAAG,CACH,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CACxE,CAAC,EACD,GAAG,CACH,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAG,IAAI,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;IACzC,IAAI,QAAQ,GAAG,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,EAAE,CAAC;IAE9C,IAAI,EAAE,EAAE,CAAC;QACR,MAAM,MAAM,GAAG,MAAM,CACpB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAClD,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACnB,QAAQ,GAAG,GAAG,QAAQ,GAAG,GAAG,GAAG,MAAM,EAAE,CAAC;IACzC,CAAC;IAED,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,QAAQ,GAAG,GAAG,GAAG,QAAQ,EAAE,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"format_dt.js","sourceRoot":"","sources":["../../../../src/utils/format_dt.ts"],"names":[],"mappings":";;AA8EA,0BAkDC;AA1FD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,SAAgB,OAAO,CAAC,IAAkB,EAAE,OAAwB;IACnE,MAAM,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;IAC7B,MAAM,EACL,SAAS,GAAG,GAAG,EACf,EAAE,GAAG,KAAK,EACV,EAAE,GAAG,KAAK,EACV,KAAK,GAAG,UAAU,EAClB,QAAQ,GAAG,KAAK,GAChB,GAAG,OAAO,IAAI,EAAE,CAAC;IAElB,MAAM,GAAG,GAAG,EAAE,KAAK,KAAK,CAAC;IAEzB,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CACxE,CAAC,EACD,GAAG,CACH,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CACxE,CAAC,EACD,GAAG,CACH,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CACxE,CAAC,EACD,GAAG,CACH,CAAC;IAEF,MAAM,QAAQ,GAAG,QAAQ;QACxB,CAAC,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,EAAE;QAC3B,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;IAC3B,IAAI,QAAQ,GAAG,QAAQ;QACtB,CAAC,CAAC,GAAG,KAAK,IAAI,OAAO,IAAI,OAAO,EAAE;QAClC,CAAC,CAAC,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,EAAE,CAAC;IAElC,IAAI,EAAE,EAAE,CAAC;QACR,MAAM,MAAM,GAAG,MAAM,CACpB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAClD,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACnB,MAAM,KAAK,GAAG,QAAQ,IAAI,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7D,QAAQ,GAAG,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,EAAE,CAAC;AAC7C,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export * from "./format_dt";
2
+ export * from "./logger";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC"}
@@ -15,4 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./format_dt"), exports);
18
+ __exportStar(require("./logger"), exports);
18
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,2CAAyB"}
@@ -0,0 +1,271 @@
1
+ /**
2
+ * @fileoverview Structured logging utility with transport DI and Err integration.
3
+ *
4
+ * This module provides a flexible, callable logger with a transport abstraction,
5
+ * built-in pretty console transport, and zero external runtime dependencies
6
+ * beyond `fast-safe-stringify`.
7
+ *
8
+ * ## Design Philosophy
9
+ *
10
+ * The logger is designed as a callable function with overloaded signatures.
11
+ * Transports are injectable, making the logger testable without streams or
12
+ * process-level side effects. The built-in pretty transport renders to stderr
13
+ * with ANSI colors and automatic Err formatting.
14
+ *
15
+ * ## Basic Usage
16
+ *
17
+ * @example Simple logging
18
+ * ```typescript
19
+ * import { log } from './utils/logger';
20
+ *
21
+ * log('Application started'); // INFO level by default
22
+ * log(log.WARN, 'Connection slow'); // Explicit level
23
+ * log(log.ERROR, 'Failed to save', { userId: '123' }); // With context
24
+ * ```
25
+ *
26
+ * @example Logging with Err instances
27
+ * ```typescript
28
+ * import { Err } from './types/err';
29
+ * import { log } from './utils/logger';
30
+ *
31
+ * const [data, err] = fetchData();
32
+ * if (err) {
33
+ * log(log.ERROR, 'Data fetch failed', err);
34
+ * return;
35
+ * }
36
+ * ```
37
+ *
38
+ * @example Child loggers with module context
39
+ * ```typescript
40
+ * const dbLogger = log.child('database', { version: '1.0' });
41
+ * dbLogger('Connected to postgres');
42
+ * // Output: [database] Connected to postgres
43
+ *
44
+ * const userLogger = dbLogger.child('users');
45
+ * userLogger('User created');
46
+ * // Output: [database] [users] User created
47
+ * ```
48
+ *
49
+ * @example Custom transport for testing
50
+ * ```typescript
51
+ * import { createLogger, lvl } from './utils/logger';
52
+ * import type { LogEntry, LogTransport } from './utils/logger';
53
+ *
54
+ * const entries: LogEntry[] = [];
55
+ * const spy: LogTransport = { write(e) { entries.push(e); } };
56
+ * const testLogger = createLogger('test', { transports: [spy], level: lvl.TRACE });
57
+ * ```
58
+ *
59
+ * ## Configuration
60
+ *
61
+ * The logger reads configuration from environment variables:
62
+ * - `LOG_LEVEL`: Minimum level to log (trace|debug|info|warn|error|fatal). Default: 'info'
63
+ *
64
+ * @module logger
65
+ */
66
+ import { Err } from "../types/err";
67
+ /**
68
+ * Log level constants for type-safe level specification.
69
+ *
70
+ * **Level Hierarchy** (lowest to highest):
71
+ * - `TRACE`: Detailed debugging information
72
+ * - `DEBUG`: Debugging information
73
+ * - `INFO`: General informational messages
74
+ * - `WARN`: Warning messages
75
+ * - `ERROR`: Error messages for failures
76
+ * - `FATAL`: Fatal errors causing termination
77
+ */
78
+ declare const lvl: {
79
+ readonly TRACE: "trace";
80
+ readonly DEBUG: "debug";
81
+ readonly INFO: "info";
82
+ readonly WARN: "warn";
83
+ readonly ERROR: "error";
84
+ readonly FATAL: "fatal";
85
+ };
86
+ /**
87
+ * Type representing valid log level values.
88
+ */
89
+ type LevelValue = (typeof lvl)[keyof typeof lvl];
90
+ /**
91
+ * A single structured log entry passed to transports.
92
+ */
93
+ interface LogEntry {
94
+ /** Log level */
95
+ level: LevelValue;
96
+ /** Unix timestamp in milliseconds (Date.now()) */
97
+ timestamp: number;
98
+ /** Log message */
99
+ message: string;
100
+ /** Merged bindings + call-site context */
101
+ context: Record<string, unknown>;
102
+ /** Module chain accumulated by child() calls */
103
+ modules: string[];
104
+ }
105
+ /**
106
+ * Transport interface — receives a `LogEntry` for each log call that passes
107
+ * the level filter. Implement this to integrate any logging backend.
108
+ *
109
+ * @example Pino transport
110
+ * ```typescript
111
+ * import pino from 'pino';
112
+ * import type { LogTransport, LogEntry } from '@pencroff-lab/kore';
113
+ *
114
+ * const pinoInstance = pino();
115
+ * const pinoTransport: LogTransport = {
116
+ * write(entry: LogEntry) {
117
+ * const prefix = entry.modules.map(m => `[${m}] `).join('');
118
+ * pinoInstance[entry.level](entry.context, prefix + entry.message);
119
+ * }
120
+ * };
121
+ * ```
122
+ */
123
+ interface LogTransport {
124
+ write(entry: LogEntry): void;
125
+ }
126
+ /**
127
+ * Options for the built-in pretty console transport.
128
+ */
129
+ interface PrettyOptions {
130
+ /** Output stream. Default: `process.stderr` */
131
+ output?: {
132
+ write(data: string): void;
133
+ };
134
+ /**
135
+ * Enable ANSI colors.
136
+ * - `'auto'` (default): enable when output is a TTY
137
+ * - `true`: always enable
138
+ * - `false`: always disable
139
+ */
140
+ colors?: boolean | "auto";
141
+ /** Override default level colors (ANSI escape sequences) */
142
+ levelColors?: Partial<Record<LevelValue, string>>;
143
+ /**
144
+ * Timestamp format.
145
+ * - `'short'` (default): `HH:MM:SS.mmm` local time
146
+ * - `'iso'`: ISO 8601 string
147
+ * - Custom function receiving `Date.now()` timestamp
148
+ */
149
+ timestamp?: "short" | "iso" | ((ts: number) => string);
150
+ }
151
+ /**
152
+ * Options for `createLogger`.
153
+ */
154
+ interface LoggerOptions {
155
+ /** Minimum log level. Default: from `LOG_LEVEL` env or `'info'` */
156
+ level?: LevelValue;
157
+ /** Transports to write entries to. Default: `[prettyTransport()]` */
158
+ transports?: LogTransport[];
159
+ }
160
+ /**
161
+ * Callable logger interface with overloaded signatures.
162
+ *
163
+ * The Logger is both a function (for logging) and an object (with level
164
+ * constants and the `child` method).
165
+ *
166
+ * ## Call Signatures
167
+ * 1. `log(message)` - Log at INFO level
168
+ * 2. `log(message, context)` - Log at INFO level with context object or Err
169
+ * 3. `log(message, detail)` - Log at INFO level with detail string
170
+ * 4. `log(level, message)` - Log at specific level
171
+ * 5. `log(level, message, context)` - Log at specific level with context
172
+ */
173
+ interface Logger {
174
+ /** Trace level constant */
175
+ readonly TRACE: "trace";
176
+ /** Debug level constant */
177
+ readonly DEBUG: "debug";
178
+ /** Info level constant */
179
+ readonly INFO: "info";
180
+ /** Warning level constant */
181
+ readonly WARN: "warn";
182
+ /** Error level constant */
183
+ readonly ERROR: "error";
184
+ /** Fatal level constant */
185
+ readonly FATAL: "fatal";
186
+ /** Log a message at INFO level. */
187
+ (message: string): void;
188
+ /** Log a message at INFO level with context. */
189
+ (message: string, context: object | Err): void;
190
+ /** Log a message at INFO level with detail string. */
191
+ (message: string, detail: string): void;
192
+ /** Log a message at a specific level. */
193
+ (level: LevelValue, message: string): void;
194
+ /** Log a message at a specific level with context. */
195
+ (level: LevelValue, message: string, context: object | Err): void;
196
+ /**
197
+ * Create a child logger with module-specific context.
198
+ *
199
+ * @param module - Module name added to the modules array
200
+ * @param bindings - Optional bindings merged into every log entry's context
201
+ * @returns New Logger instance
202
+ */
203
+ child(module: string, bindings?: object): Logger;
204
+ }
205
+ /**
206
+ * Create a built-in pretty console transport.
207
+ *
208
+ * Renders log entries to a human-readable format with optional ANSI colors.
209
+ *
210
+ * Output format:
211
+ * ```
212
+ * {dim timestamp} {colored TAG} {[mod] [mod]} {message} {dim context}
213
+ * ```
214
+ *
215
+ * Err instances in context are rendered via `Err.toString()` on their own
216
+ * indented line below the main line.
217
+ *
218
+ * @param options - Optional configuration
219
+ */
220
+ declare function prettyTransport(options?: PrettyOptions): LogTransport;
221
+ /**
222
+ * Create a logger instance with optional module name and configuration.
223
+ *
224
+ * @param module - Optional module name added as the first entry in `modules`
225
+ * @param options - Optional configuration
226
+ * @returns New Logger instance
227
+ *
228
+ * @example Basic usage
229
+ * ```typescript
230
+ * const logger = createLogger();
231
+ * logger('Application ready');
232
+ * ```
233
+ *
234
+ * @example Module-specific logger
235
+ * ```typescript
236
+ * const dbLogger = createLogger('database');
237
+ * dbLogger('Connected');
238
+ * ```
239
+ *
240
+ * @example Testing with spy transport
241
+ * ```typescript
242
+ * import type { LogEntry, LogTransport } from './utils/logger';
243
+ *
244
+ * const entries: LogEntry[] = [];
245
+ * const spy: LogTransport = { write(e) { entries.push(e); } };
246
+ * const testLogger = createLogger('test', { transports: [spy], level: lvl.TRACE });
247
+ * ```
248
+ */
249
+ declare function createLogger(module?: string, options?: LoggerOptions): Logger;
250
+ /**
251
+ * Default logger instance for application-wide logging.
252
+ *
253
+ * @example Basic usage
254
+ * ```typescript
255
+ * import { log } from './utils/logger';
256
+ *
257
+ * log('Application started');
258
+ * log(log.INFO, 'Server listening', { port: 3000 });
259
+ * log(log.ERROR, 'Startup failed', err);
260
+ * ```
261
+ *
262
+ * @example Module-specific logging via child
263
+ * ```typescript
264
+ * const dbLogger = log.child('database');
265
+ * dbLogger('Connection pool initialized');
266
+ * ```
267
+ */
268
+ export declare const log: Logger;
269
+ export { createLogger, prettyTransport, lvl };
270
+ export type { Logger, LevelValue, LogEntry, LogTransport, LoggerOptions, PrettyOptions, };
271
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../src/utils/logger.ts"],"names":[],"mappings":"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"}