@logtape/logtape 0.6.0-dev.71 → 0.6.0-dev.74

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/esm/formatter.js CHANGED
@@ -1,4 +1,4 @@
1
- import * as dntShim from "./_dnt.shims.js";
1
+ import util from "node:util";
2
2
  /**
3
3
  * The severity level abbreviations.
4
4
  */
@@ -21,18 +21,96 @@ const levelAbbreviations = {
21
21
  */
22
22
  const inspect =
23
23
  // @ts-ignore: Deno global
24
- "Deno" in dntShim.dntGlobalThis && "inspect" in globalThis.Deno &&
24
+ // dnt-shim-ignore
25
+ "Deno" in globalThis && "inspect" in globalThis.Deno &&
25
26
  // @ts-ignore: Deno global
27
+ // dnt-shim-ignore
26
28
  typeof globalThis.Deno.inspect === "function"
27
29
  // @ts-ignore: Deno global
30
+ // dnt-shim-ignore
28
31
  ? globalThis.Deno.inspect.bind(globalThis.Deno)
29
32
  // @ts-ignore: Node.js global
30
- : "util" in dntShim.dntGlobalThis && "inspect" in globalThis.util &&
33
+ // dnt-shim-ignore
34
+ : "inspect" in util && typeof util.inspect === "function"
31
35
  // @ts-ignore: Node.js global
32
- globalThis.util.inspect === "function"
33
- // @ts-ignore: Node.js global
34
- ? globalThis.util.inspect.bind(globalThis.util)
35
- : JSON.stringify;
36
+ // dnt-shim-ignore
37
+ ? util.inspect.bind(util)
38
+ : (v) => JSON.stringify(v);
39
+ /**
40
+ * Get a text formatter with the specified options. Although it's flexible
41
+ * enough to create a custom formatter, if you want more control, you can
42
+ * create a custom formatter that satisfies the {@link TextFormatter} type
43
+ * instead.
44
+ *
45
+ * For more information on the options, see {@link TextFormatterOptions}.
46
+ *
47
+ * By default, the formatter formats log records as follows:
48
+ *
49
+ * ```
50
+ * 2023-11-14 22:13:20.000 +00:00 [INF] category·subcategory: Hello, world!
51
+ * ```
52
+ * @param options The options for the text formatter.
53
+ * @returns The text formatter.
54
+ * @since 0.6.0
55
+ */
56
+ export function getTextFormatter(options = {}) {
57
+ const timestampRenderer = options.timestamp == null || options.timestamp === "date-time-timezone"
58
+ ? (ts) => new Date(ts).toISOString().replace("T", " ").replace("Z", " +00:00")
59
+ : options.timestamp === "date-time-tz"
60
+ ? (ts) => new Date(ts).toISOString().replace("T", " ").replace("Z", " +00")
61
+ : options.timestamp === "date-time"
62
+ ? (ts) => new Date(ts).toISOString().replace("T", " ").replace("Z", "")
63
+ : options.timestamp === "time-timezone"
64
+ ? (ts) => new Date(ts).toISOString().replace(/.*T/, "").replace("Z", " +00:00")
65
+ : options.timestamp === "time-tz"
66
+ ? (ts) => new Date(ts).toISOString().replace(/.*T/, "").replace("Z", " +00")
67
+ : options.timestamp === "time"
68
+ ? (ts) => new Date(ts).toISOString().replace(/.*T/, "").replace("Z", "")
69
+ : options.timestamp === "date"
70
+ ? (ts) => new Date(ts).toISOString().replace(/T.*/, "")
71
+ : options.timestamp === "rfc3339"
72
+ ? (ts) => new Date(ts).toISOString()
73
+ : options.timestamp;
74
+ const categorySeparator = options.category ?? "·";
75
+ const valueRenderer = options.value ?? inspect;
76
+ const levelRenderer = options.level == null || options.level === "ABBR"
77
+ ? (level) => levelAbbreviations[level]
78
+ : options.level === "abbr"
79
+ ? (level) => levelAbbreviations[level].toLowerCase()
80
+ : options.level === "FULL"
81
+ ? (level) => level.toUpperCase()
82
+ : options.level === "full"
83
+ ? (level) => level
84
+ : options.level === "L"
85
+ ? (level) => level.charAt(0).toUpperCase()
86
+ : options.level === "l"
87
+ ? (level) => level.charAt(0)
88
+ : options.level;
89
+ const formatter = options.format ??
90
+ (({ timestamp, level, category, message }) => `${timestamp} [${level}] ${category}: ${message}`);
91
+ return (record) => {
92
+ let message = "";
93
+ for (let i = 0; i < record.message.length; i++) {
94
+ if (i % 2 === 0)
95
+ message += record.message[i];
96
+ else
97
+ message += valueRenderer(record.message[i]);
98
+ }
99
+ const timestamp = timestampRenderer(record.timestamp);
100
+ const level = levelRenderer(record.level);
101
+ const category = typeof categorySeparator === "function"
102
+ ? categorySeparator(record.category)
103
+ : record.category.join(categorySeparator);
104
+ const values = {
105
+ timestamp,
106
+ level,
107
+ category,
108
+ message,
109
+ record,
110
+ };
111
+ return `${formatter(values)}\n`;
112
+ };
113
+ }
36
114
  /**
37
115
  * The default text formatter. This formatter formats log records as follows:
38
116
  *
@@ -43,28 +121,84 @@ const inspect =
43
121
  * @param record The log record to format.
44
122
  * @returns The formatted log record.
45
123
  */
46
- export function defaultTextFormatter(record) {
47
- const ts = new Date(record.timestamp);
48
- let msg = "";
49
- for (let i = 0; i < record.message.length; i++) {
50
- if (i % 2 === 0)
51
- msg += record.message[i];
52
- else
53
- msg += inspect(record.message[i]);
54
- }
55
- const category = record.category.join("\xb7");
56
- return `${ts.toISOString().replace("T", " ").replace("Z", " +00:00")} [${levelAbbreviations[record.level]}] ${category}: ${msg}\n`;
57
- }
124
+ export const defaultTextFormatter = getTextFormatter();
58
125
  const RESET = "\x1b[0m";
59
- const BOLD = "\x1b[1m";
60
- const DIM = "\x1b[2m";
61
- const levelColors = {
62
- debug: "\x1b[34m", // Blue
63
- info: "\x1b[32m", // Green
64
- warning: "\x1b[33m", // Yellow
65
- error: "\x1b[31m", // Red
66
- fatal: "\x1b[35m", // Magenta
126
+ const ansiColors = {
127
+ black: "\x1b[30m",
128
+ red: "\x1b[31m",
129
+ green: "\x1b[32m",
130
+ yellow: "\x1b[33m",
131
+ blue: "\x1b[34m",
132
+ magenta: "\x1b[35m",
133
+ cyan: "\x1b[36m",
134
+ white: "\x1b[37m",
135
+ };
136
+ const ansiStyles = {
137
+ bold: "\x1b[1m",
138
+ dim: "\x1b[2m",
139
+ italic: "\x1b[3m",
140
+ underline: "\x1b[4m",
141
+ strikethrough: "\x1b[9m",
142
+ };
143
+ const defaultLevelColors = {
144
+ debug: "blue",
145
+ info: "green",
146
+ warning: "yellow",
147
+ error: "red",
148
+ fatal: "magenta",
67
149
  };
150
+ /**
151
+ * Get an ANSI color formatter with the specified options.
152
+ *
153
+ * ![A preview of an ANSI color formatter.](https://i.imgur.com/I8LlBUf.png)
154
+ * @param option The options for the ANSI color formatter.
155
+ * @returns The ANSI color formatter.
156
+ * @since 0.6.0
157
+ */
158
+ export function getAnsiColorFormatter(options = {}) {
159
+ const format = options.format;
160
+ const timestampStyle = typeof options.timestampStyle === "undefined"
161
+ ? "dim"
162
+ : options.timestampStyle;
163
+ const timestampColor = options.timestampColor ?? null;
164
+ const timestampPrefix = `${timestampStyle == null ? "" : ansiStyles[timestampStyle]}${timestampColor == null ? "" : ansiColors[timestampColor]}`;
165
+ const timestampSuffix = timestampStyle == null && timestampColor == null
166
+ ? ""
167
+ : RESET;
168
+ const levelStyle = typeof options.levelStyle === "undefined"
169
+ ? "bold"
170
+ : options.levelStyle;
171
+ const levelColors = options.levelColors ?? defaultLevelColors;
172
+ const categoryStyle = typeof options.categoryStyle === "undefined"
173
+ ? "dim"
174
+ : options.categoryStyle;
175
+ const categoryColor = options.categoryColor ?? null;
176
+ const categoryPrefix = `${categoryStyle == null ? "" : ansiStyles[categoryStyle]}${categoryColor == null ? "" : ansiColors[categoryColor]}`;
177
+ const categorySuffix = categoryStyle == null && categoryColor == null
178
+ ? ""
179
+ : RESET;
180
+ return getTextFormatter({
181
+ timestamp: "date-time-tz",
182
+ value(value) {
183
+ return inspect(value, { colors: true });
184
+ },
185
+ ...options,
186
+ format({ timestamp, level, category, message, record }) {
187
+ const levelColor = levelColors[record.level];
188
+ timestamp = `${timestampPrefix}${timestamp}${timestampSuffix}`;
189
+ level = `${levelStyle == null ? "" : ansiStyles[levelStyle]}${levelColor == null ? "" : ansiColors[levelColor]}${level}${levelStyle == null && levelColor == null ? "" : RESET}`;
190
+ return format == null
191
+ ? `${timestamp} ${level} ${categoryPrefix}${category}:${categorySuffix} ${message}`
192
+ : format({
193
+ timestamp,
194
+ level,
195
+ category: `${categoryPrefix}${category}${categorySuffix}`,
196
+ message,
197
+ record,
198
+ });
199
+ },
200
+ });
201
+ }
68
202
  /**
69
203
  * A text formatter that uses ANSI colors to format log records.
70
204
  *
@@ -74,25 +208,7 @@ const levelColors = {
74
208
  * @returns The formatted log record.
75
209
  * @since 0.5.0
76
210
  */
77
- export const ansiColorFormatter = (record) => {
78
- const ts = new Date(record.timestamp);
79
- const timeString = ts.toISOString().replace("T", " ").replace("Z", " +00");
80
- const category = record.category.join("·");
81
- const levelColor = levelColors[record.level];
82
- const levelAbbr = levelAbbreviations[record.level];
83
- let message = "";
84
- for (let i = 0; i < record.message.length; i++) {
85
- if (i % 2 === 0) {
86
- message += record.message[i];
87
- }
88
- else {
89
- message += inspect(record.message[i], { colors: true });
90
- }
91
- }
92
- return `${DIM}${timeString}${RESET} ` +
93
- `${BOLD}${levelColor}${levelAbbr}${RESET} ` +
94
- `${DIM}${category}:${RESET} ${message}\n`;
95
- };
211
+ export const ansiColorFormatter = getAnsiColorFormatter();
96
212
  /**
97
213
  * The styles for the log level in the console.
98
214
  */
package/esm/mod.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export { ConfigError, configure, dispose, getConfig, reset, } from "./config.js";
2
2
  export { getFileSink, getRotatingFileSink } from "./filesink.node.js";
3
3
  export { getLevelFilter, toFilter, } from "./filter.js";
4
- export { ansiColorFormatter, defaultConsoleFormatter, defaultTextFormatter, } from "./formatter.js";
4
+ export { ansiColorFormatter, defaultConsoleFormatter, defaultTextFormatter, getAnsiColorFormatter, getTextFormatter, } from "./formatter.js";
5
5
  export { isLogLevel, parseLogLevel } from "./level.js";
6
6
  export { getLogger } from "./logger.js";
7
7
  export { getConsoleSink, getStreamSink, withFilter, } from "./sink.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logtape/logtape",
3
- "version": "0.6.0-dev.71+c9e2c42c",
3
+ "version": "0.6.0-dev.74+f4e8f8e6",
4
4
  "description": "Simple logging library with zero dependencies for Deno/Node.js/Bun/browsers",
5
5
  "keywords": [
6
6
  "logging",
@@ -1,32 +1,13 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
4
  };
25
5
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.ansiColorFormatter = void 0;
27
- exports.defaultTextFormatter = defaultTextFormatter;
6
+ exports.ansiColorFormatter = exports.defaultTextFormatter = void 0;
7
+ exports.getTextFormatter = getTextFormatter;
8
+ exports.getAnsiColorFormatter = getAnsiColorFormatter;
28
9
  exports.defaultConsoleFormatter = defaultConsoleFormatter;
29
- const dntShim = __importStar(require("./_dnt.shims.js"));
10
+ const node_util_1 = __importDefault(require("node:util"));
30
11
  /**
31
12
  * The severity level abbreviations.
32
13
  */
@@ -49,18 +30,96 @@ const levelAbbreviations = {
49
30
  */
50
31
  const inspect =
51
32
  // @ts-ignore: Deno global
52
- "Deno" in dntShim.dntGlobalThis && "inspect" in globalThis.Deno &&
33
+ // dnt-shim-ignore
34
+ "Deno" in globalThis && "inspect" in globalThis.Deno &&
53
35
  // @ts-ignore: Deno global
36
+ // dnt-shim-ignore
54
37
  typeof globalThis.Deno.inspect === "function"
55
38
  // @ts-ignore: Deno global
39
+ // dnt-shim-ignore
56
40
  ? globalThis.Deno.inspect.bind(globalThis.Deno)
57
41
  // @ts-ignore: Node.js global
58
- : "util" in dntShim.dntGlobalThis && "inspect" in globalThis.util &&
59
- // @ts-ignore: Node.js global
60
- globalThis.util.inspect === "function"
42
+ // dnt-shim-ignore
43
+ : "inspect" in node_util_1.default && typeof node_util_1.default.inspect === "function"
61
44
  // @ts-ignore: Node.js global
62
- ? globalThis.util.inspect.bind(globalThis.util)
63
- : JSON.stringify;
45
+ // dnt-shim-ignore
46
+ ? node_util_1.default.inspect.bind(node_util_1.default)
47
+ : (v) => JSON.stringify(v);
48
+ /**
49
+ * Get a text formatter with the specified options. Although it's flexible
50
+ * enough to create a custom formatter, if you want more control, you can
51
+ * create a custom formatter that satisfies the {@link TextFormatter} type
52
+ * instead.
53
+ *
54
+ * For more information on the options, see {@link TextFormatterOptions}.
55
+ *
56
+ * By default, the formatter formats log records as follows:
57
+ *
58
+ * ```
59
+ * 2023-11-14 22:13:20.000 +00:00 [INF] category·subcategory: Hello, world!
60
+ * ```
61
+ * @param options The options for the text formatter.
62
+ * @returns The text formatter.
63
+ * @since 0.6.0
64
+ */
65
+ function getTextFormatter(options = {}) {
66
+ const timestampRenderer = options.timestamp == null || options.timestamp === "date-time-timezone"
67
+ ? (ts) => new Date(ts).toISOString().replace("T", " ").replace("Z", " +00:00")
68
+ : options.timestamp === "date-time-tz"
69
+ ? (ts) => new Date(ts).toISOString().replace("T", " ").replace("Z", " +00")
70
+ : options.timestamp === "date-time"
71
+ ? (ts) => new Date(ts).toISOString().replace("T", " ").replace("Z", "")
72
+ : options.timestamp === "time-timezone"
73
+ ? (ts) => new Date(ts).toISOString().replace(/.*T/, "").replace("Z", " +00:00")
74
+ : options.timestamp === "time-tz"
75
+ ? (ts) => new Date(ts).toISOString().replace(/.*T/, "").replace("Z", " +00")
76
+ : options.timestamp === "time"
77
+ ? (ts) => new Date(ts).toISOString().replace(/.*T/, "").replace("Z", "")
78
+ : options.timestamp === "date"
79
+ ? (ts) => new Date(ts).toISOString().replace(/T.*/, "")
80
+ : options.timestamp === "rfc3339"
81
+ ? (ts) => new Date(ts).toISOString()
82
+ : options.timestamp;
83
+ const categorySeparator = options.category ?? "·";
84
+ const valueRenderer = options.value ?? inspect;
85
+ const levelRenderer = options.level == null || options.level === "ABBR"
86
+ ? (level) => levelAbbreviations[level]
87
+ : options.level === "abbr"
88
+ ? (level) => levelAbbreviations[level].toLowerCase()
89
+ : options.level === "FULL"
90
+ ? (level) => level.toUpperCase()
91
+ : options.level === "full"
92
+ ? (level) => level
93
+ : options.level === "L"
94
+ ? (level) => level.charAt(0).toUpperCase()
95
+ : options.level === "l"
96
+ ? (level) => level.charAt(0)
97
+ : options.level;
98
+ const formatter = options.format ??
99
+ (({ timestamp, level, category, message }) => `${timestamp} [${level}] ${category}: ${message}`);
100
+ return (record) => {
101
+ let message = "";
102
+ for (let i = 0; i < record.message.length; i++) {
103
+ if (i % 2 === 0)
104
+ message += record.message[i];
105
+ else
106
+ message += valueRenderer(record.message[i]);
107
+ }
108
+ const timestamp = timestampRenderer(record.timestamp);
109
+ const level = levelRenderer(record.level);
110
+ const category = typeof categorySeparator === "function"
111
+ ? categorySeparator(record.category)
112
+ : record.category.join(categorySeparator);
113
+ const values = {
114
+ timestamp,
115
+ level,
116
+ category,
117
+ message,
118
+ record,
119
+ };
120
+ return `${formatter(values)}\n`;
121
+ };
122
+ }
64
123
  /**
65
124
  * The default text formatter. This formatter formats log records as follows:
66
125
  *
@@ -71,28 +130,84 @@ const inspect =
71
130
  * @param record The log record to format.
72
131
  * @returns The formatted log record.
73
132
  */
74
- function defaultTextFormatter(record) {
75
- const ts = new Date(record.timestamp);
76
- let msg = "";
77
- for (let i = 0; i < record.message.length; i++) {
78
- if (i % 2 === 0)
79
- msg += record.message[i];
80
- else
81
- msg += inspect(record.message[i]);
82
- }
83
- const category = record.category.join("\xb7");
84
- return `${ts.toISOString().replace("T", " ").replace("Z", " +00:00")} [${levelAbbreviations[record.level]}] ${category}: ${msg}\n`;
85
- }
133
+ exports.defaultTextFormatter = getTextFormatter();
86
134
  const RESET = "\x1b[0m";
87
- const BOLD = "\x1b[1m";
88
- const DIM = "\x1b[2m";
89
- const levelColors = {
90
- debug: "\x1b[34m", // Blue
91
- info: "\x1b[32m", // Green
92
- warning: "\x1b[33m", // Yellow
93
- error: "\x1b[31m", // Red
94
- fatal: "\x1b[35m", // Magenta
135
+ const ansiColors = {
136
+ black: "\x1b[30m",
137
+ red: "\x1b[31m",
138
+ green: "\x1b[32m",
139
+ yellow: "\x1b[33m",
140
+ blue: "\x1b[34m",
141
+ magenta: "\x1b[35m",
142
+ cyan: "\x1b[36m",
143
+ white: "\x1b[37m",
144
+ };
145
+ const ansiStyles = {
146
+ bold: "\x1b[1m",
147
+ dim: "\x1b[2m",
148
+ italic: "\x1b[3m",
149
+ underline: "\x1b[4m",
150
+ strikethrough: "\x1b[9m",
151
+ };
152
+ const defaultLevelColors = {
153
+ debug: "blue",
154
+ info: "green",
155
+ warning: "yellow",
156
+ error: "red",
157
+ fatal: "magenta",
95
158
  };
159
+ /**
160
+ * Get an ANSI color formatter with the specified options.
161
+ *
162
+ * ![A preview of an ANSI color formatter.](https://i.imgur.com/I8LlBUf.png)
163
+ * @param option The options for the ANSI color formatter.
164
+ * @returns The ANSI color formatter.
165
+ * @since 0.6.0
166
+ */
167
+ function getAnsiColorFormatter(options = {}) {
168
+ const format = options.format;
169
+ const timestampStyle = typeof options.timestampStyle === "undefined"
170
+ ? "dim"
171
+ : options.timestampStyle;
172
+ const timestampColor = options.timestampColor ?? null;
173
+ const timestampPrefix = `${timestampStyle == null ? "" : ansiStyles[timestampStyle]}${timestampColor == null ? "" : ansiColors[timestampColor]}`;
174
+ const timestampSuffix = timestampStyle == null && timestampColor == null
175
+ ? ""
176
+ : RESET;
177
+ const levelStyle = typeof options.levelStyle === "undefined"
178
+ ? "bold"
179
+ : options.levelStyle;
180
+ const levelColors = options.levelColors ?? defaultLevelColors;
181
+ const categoryStyle = typeof options.categoryStyle === "undefined"
182
+ ? "dim"
183
+ : options.categoryStyle;
184
+ const categoryColor = options.categoryColor ?? null;
185
+ const categoryPrefix = `${categoryStyle == null ? "" : ansiStyles[categoryStyle]}${categoryColor == null ? "" : ansiColors[categoryColor]}`;
186
+ const categorySuffix = categoryStyle == null && categoryColor == null
187
+ ? ""
188
+ : RESET;
189
+ return getTextFormatter({
190
+ timestamp: "date-time-tz",
191
+ value(value) {
192
+ return inspect(value, { colors: true });
193
+ },
194
+ ...options,
195
+ format({ timestamp, level, category, message, record }) {
196
+ const levelColor = levelColors[record.level];
197
+ timestamp = `${timestampPrefix}${timestamp}${timestampSuffix}`;
198
+ level = `${levelStyle == null ? "" : ansiStyles[levelStyle]}${levelColor == null ? "" : ansiColors[levelColor]}${level}${levelStyle == null && levelColor == null ? "" : RESET}`;
199
+ return format == null
200
+ ? `${timestamp} ${level} ${categoryPrefix}${category}:${categorySuffix} ${message}`
201
+ : format({
202
+ timestamp,
203
+ level,
204
+ category: `${categoryPrefix}${category}${categorySuffix}`,
205
+ message,
206
+ record,
207
+ });
208
+ },
209
+ });
210
+ }
96
211
  /**
97
212
  * A text formatter that uses ANSI colors to format log records.
98
213
  *
@@ -102,26 +217,7 @@ const levelColors = {
102
217
  * @returns The formatted log record.
103
218
  * @since 0.5.0
104
219
  */
105
- const ansiColorFormatter = (record) => {
106
- const ts = new Date(record.timestamp);
107
- const timeString = ts.toISOString().replace("T", " ").replace("Z", " +00");
108
- const category = record.category.join("·");
109
- const levelColor = levelColors[record.level];
110
- const levelAbbr = levelAbbreviations[record.level];
111
- let message = "";
112
- for (let i = 0; i < record.message.length; i++) {
113
- if (i % 2 === 0) {
114
- message += record.message[i];
115
- }
116
- else {
117
- message += inspect(record.message[i], { colors: true });
118
- }
119
- }
120
- return `${DIM}${timeString}${RESET} ` +
121
- `${BOLD}${levelColor}${levelAbbr}${RESET} ` +
122
- `${DIM}${category}:${RESET} ${message}\n`;
123
- };
124
- exports.ansiColorFormatter = ansiColorFormatter;
220
+ exports.ansiColorFormatter = getAnsiColorFormatter();
125
221
  /**
126
222
  * The styles for the log level in the console.
127
223
  */
package/script/mod.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.withFilter = exports.getStreamSink = exports.getConsoleSink = exports.getLogger = exports.parseLogLevel = exports.isLogLevel = exports.defaultTextFormatter = exports.defaultConsoleFormatter = exports.ansiColorFormatter = exports.toFilter = exports.getLevelFilter = exports.getRotatingFileSink = exports.getFileSink = exports.reset = exports.getConfig = exports.dispose = exports.configure = exports.ConfigError = void 0;
3
+ exports.withFilter = exports.getStreamSink = exports.getConsoleSink = exports.getLogger = exports.parseLogLevel = exports.isLogLevel = exports.getTextFormatter = exports.getAnsiColorFormatter = exports.defaultTextFormatter = exports.defaultConsoleFormatter = exports.ansiColorFormatter = exports.toFilter = exports.getLevelFilter = exports.getRotatingFileSink = exports.getFileSink = exports.reset = exports.getConfig = exports.dispose = exports.configure = exports.ConfigError = void 0;
4
4
  var config_js_1 = require("./config.js");
5
5
  Object.defineProperty(exports, "ConfigError", { enumerable: true, get: function () { return config_js_1.ConfigError; } });
6
6
  Object.defineProperty(exports, "configure", { enumerable: true, get: function () { return config_js_1.configure; } });
@@ -17,6 +17,8 @@ var formatter_js_1 = require("./formatter.js");
17
17
  Object.defineProperty(exports, "ansiColorFormatter", { enumerable: true, get: function () { return formatter_js_1.ansiColorFormatter; } });
18
18
  Object.defineProperty(exports, "defaultConsoleFormatter", { enumerable: true, get: function () { return formatter_js_1.defaultConsoleFormatter; } });
19
19
  Object.defineProperty(exports, "defaultTextFormatter", { enumerable: true, get: function () { return formatter_js_1.defaultTextFormatter; } });
20
+ Object.defineProperty(exports, "getAnsiColorFormatter", { enumerable: true, get: function () { return formatter_js_1.getAnsiColorFormatter; } });
21
+ Object.defineProperty(exports, "getTextFormatter", { enumerable: true, get: function () { return formatter_js_1.getTextFormatter; } });
20
22
  var level_js_1 = require("./level.js");
21
23
  Object.defineProperty(exports, "isLogLevel", { enumerable: true, get: function () { return level_js_1.isLogLevel; } });
22
24
  Object.defineProperty(exports, "parseLogLevel", { enumerable: true, get: function () { return level_js_1.parseLogLevel; } });
@@ -1,3 +1,4 @@
1
+ import type { LogLevel } from "./level.js";
1
2
  import type { LogRecord } from "./record.js";
2
3
  /**
3
4
  * A text formatter is a function that accepts a log record and returns
@@ -7,6 +8,129 @@ import type { LogRecord } from "./record.js";
7
8
  * @returns The formatted log record.
8
9
  */
9
10
  export type TextFormatter = (record: LogRecord) => string;
11
+ /**
12
+ * The formatted values for a log record.
13
+ * @since 0.6.0
14
+ */
15
+ export interface FormattedValues {
16
+ /**
17
+ * The formatted timestamp.
18
+ */
19
+ timestamp: string;
20
+ /**
21
+ * The formatted log level.
22
+ */
23
+ level: string;
24
+ /**
25
+ * The formatted category.
26
+ */
27
+ category: string;
28
+ /**
29
+ * The formatted message.
30
+ */
31
+ message: string;
32
+ /**
33
+ * The unformatted log record.
34
+ */
35
+ record: LogRecord;
36
+ }
37
+ /**
38
+ * The various options for the built-in text formatters.
39
+ * @since 0.6.0
40
+ */
41
+ export interface TextFormatterOptions {
42
+ /**
43
+ * The timestamp format. This can be one of the following:
44
+ *
45
+ * - `"date-time-timezone"`: The date and time with the full timezone offset
46
+ * (e.g., `"2023-11-14 22:13:20.000 +00:00"`).
47
+ * - `"date-time-tz"`: The date and time with the short timezone offset
48
+ * (e.g., `"2023-11-14 22:13:20.000 +00"`).
49
+ * - `"date-time"`: The date and time without the timezone offset
50
+ * (e.g., `"2023-11-14 22:13:20.000"`).
51
+ * - `"time-timezone"`: The time with the full timezone offset but without
52
+ * the date (e.g., `"22:13:20.000 +00:00"`).
53
+ * - `"time-tz"`: The time with the short timezone offset but without the date
54
+ * (e.g., `"22:13:20.000 +00"`).
55
+ * - `"time"`: The time without the date or timezone offset
56
+ * (e.g., `"22:13:20.000"`).
57
+ * - `"date"`: The date without the time or timezone offset
58
+ * (e.g., `"2023-11-14"`).
59
+ * - `"rfc3339"`: The date and time in RFC 3339 format
60
+ * (e.g., `"2023-11-14T22:13:20.000Z"`).
61
+ *
62
+ * Alternatively, this can be a function that accepts a timestamp and returns
63
+ * a string.
64
+ *
65
+ * The default is `"date-time-timezone"`.
66
+ */
67
+ timestamp?: "date-time-timezone" | "date-time-tz" | "date-time" | "time-timezone" | "time-tz" | "time" | "date" | "rfc3339" | ((ts: number) => string);
68
+ /**
69
+ * The log level format. This can be one of the following:
70
+ *
71
+ * - `"ABBR"`: The log level abbreviation in uppercase (e.g., `"INF"`).
72
+ * - `"FULL"`: The full log level name in uppercase (e.g., `"INFO"`).
73
+ * - `"L"`: The first letter of the log level in uppercase (e.g., `"I"`).
74
+ * - `"abbr"`: The log level abbreviation in lowercase (e.g., `"inf"`).
75
+ * - `"full"`: The full log level name in lowercase (e.g., `"info"`).
76
+ * - `"l"`: The first letter of the log level in lowercase (e.g., `"i"`).
77
+ *
78
+ * Alternatively, this can be a function that accepts a log level and returns
79
+ * a string.
80
+ *
81
+ * The default is `"ABBR"`.
82
+ */
83
+ level?: "ABBR" | "FULL" | "L" | "abbr" | "full" | "l" | ((level: LogLevel) => string);
84
+ /**
85
+ * The separator between category names. For example, if the separator is
86
+ * `"·"`, the category `["a", "b", "c"]` will be formatted as `"a·b·c"`.
87
+ * The default separator is `"·"`.
88
+ *
89
+ * If this is a function, it will be called with the category array and
90
+ * should return a string, which will be used as the category string.
91
+ */
92
+ category?: string | ((category: readonly string[]) => string);
93
+ /**
94
+ * A function that renders a value to a string. This function is used to
95
+ * render the values in the log record. The default is `util.inspect` in
96
+ * Node.js/Bun and `Deno.inspect` in Deno.
97
+ * @param value The value to render.
98
+ * @returns The string representation of the value.
99
+ */
100
+ value?: (value: unknown) => string;
101
+ /**
102
+ * A function that formats the log record. This function is called with the
103
+ * formatted values and should return a string. Note that the formatted
104
+ * *should not* include a newline character at the end.
105
+ *
106
+ * By default, this is a function that formats the log record as follows:
107
+ *
108
+ * ```
109
+ * 2023-11-14 22:13:20.000 +00:00 [INF] category·subcategory: Hello, world!
110
+ * ```
111
+ * @param values The formatted values.
112
+ * @returns The formatted log record.
113
+ */
114
+ format?: (values: FormattedValues) => string;
115
+ }
116
+ /**
117
+ * Get a text formatter with the specified options. Although it's flexible
118
+ * enough to create a custom formatter, if you want more control, you can
119
+ * create a custom formatter that satisfies the {@link TextFormatter} type
120
+ * instead.
121
+ *
122
+ * For more information on the options, see {@link TextFormatterOptions}.
123
+ *
124
+ * By default, the formatter formats log records as follows:
125
+ *
126
+ * ```
127
+ * 2023-11-14 22:13:20.000 +00:00 [INF] category·subcategory: Hello, world!
128
+ * ```
129
+ * @param options The options for the text formatter.
130
+ * @returns The text formatter.
131
+ * @since 0.6.0
132
+ */
133
+ export declare function getTextFormatter(options?: TextFormatterOptions): TextFormatter;
10
134
  /**
11
135
  * The default text formatter. This formatter formats log records as follows:
12
136
  *
@@ -17,7 +141,88 @@ export type TextFormatter = (record: LogRecord) => string;
17
141
  * @param record The log record to format.
18
142
  * @returns The formatted log record.
19
143
  */
20
- export declare function defaultTextFormatter(record: LogRecord): string;
144
+ export declare const defaultTextFormatter: TextFormatter;
145
+ /**
146
+ * The ANSI colors. These can be used to colorize text in the console.
147
+ * @since 0.6.0
148
+ */
149
+ export type AnsiColor = "black" | "red" | "green" | "yellow" | "blue" | "magenta" | "cyan" | "white";
150
+ /**
151
+ * The ANSI text styles.
152
+ * @since 0.6.0
153
+ */
154
+ export type AnsiStyle = "bold" | "dim" | "italic" | "underline" | "strikethrough";
155
+ /**
156
+ * The various options for the ANSI color formatter.
157
+ * @since 0.6.0
158
+ */
159
+ export interface AnsiColorFormatterOptions extends TextFormatterOptions {
160
+ /**
161
+ * The timestamp format. This can be one of the following:
162
+ *
163
+ * - `"date-time-timezone"`: The date and time with the full timezone offset
164
+ * (e.g., `"2023-11-14 22:13:20.000 +00:00"`).
165
+ * - `"date-time-tz"`: The date and time with the short timezone offset
166
+ * (e.g., `"2023-11-14 22:13:20.000 +00"`).
167
+ * - `"date-time"`: The date and time without the timezone offset
168
+ * (e.g., `"2023-11-14 22:13:20.000"`).
169
+ * - `"time-timezone"`: The time with the full timezone offset but without
170
+ * the date (e.g., `"22:13:20.000 +00:00"`).
171
+ * - `"time-tz"`: The time with the short timezone offset but without the date
172
+ * (e.g., `"22:13:20.000 +00"`).
173
+ * - `"time"`: The time without the date or timezone offset
174
+ * (e.g., `"22:13:20.000"`).
175
+ * - `"date"`: The date without the time or timezone offset
176
+ * (e.g., `"2023-11-14"`).
177
+ * - `"rfc3339"`: The date and time in RFC 3339 format
178
+ * (e.g., `"2023-11-14T22:13:20.000Z"`).
179
+ *
180
+ * Alternatively, this can be a function that accepts a timestamp and returns
181
+ * a string.
182
+ *
183
+ * The default is `"date-time-tz"`.
184
+ */
185
+ timestamp?: "date-time-timezone" | "date-time-tz" | "date-time" | "time-timezone" | "time-tz" | "time" | "date" | "rfc3339" | ((ts: number) => string);
186
+ /**
187
+ * The ANSI style for the timestamp. `"dim"` is used by default.
188
+ */
189
+ timestampStyle?: AnsiStyle | null;
190
+ /**
191
+ * The ANSI color for the timestamp. No color is used by default.
192
+ */
193
+ timestampColor?: AnsiColor | null;
194
+ /**
195
+ * The ANSI style for the log level. `"bold"` is used by default.
196
+ */
197
+ levelStyle?: AnsiStyle | null;
198
+ /**
199
+ * The ANSI colors for the log levels. The default colors are as follows:
200
+ *
201
+ * - `"debug"`: `"blue"`
202
+ * - `"info"`: `"green"`
203
+ * - `"warning"`: `"yellow"`
204
+ * - `"error"`: `"red"`
205
+ * - `"fatal"`: `"magenta"`
206
+ */
207
+ levelColors?: Record<LogLevel, AnsiColor | null>;
208
+ /**
209
+ * The ANSI style for the category. `"dim"` is used by default.
210
+ */
211
+ categoryStyle?: AnsiStyle | null;
212
+ /**
213
+ * The ANSI color for the category. No color is used by default.
214
+ */
215
+ categoryColor?: AnsiColor | null;
216
+ }
217
+ /**
218
+ * Get an ANSI color formatter with the specified options.
219
+ *
220
+ * ![A preview of an ANSI color formatter.](https://i.imgur.com/I8LlBUf.png)
221
+ * @param option The options for the ANSI color formatter.
222
+ * @returns The ANSI color formatter.
223
+ * @since 0.6.0
224
+ */
225
+ export declare function getAnsiColorFormatter(options?: AnsiColorFormatterOptions): TextFormatter;
21
226
  /**
22
227
  * A text formatter that uses ANSI colors to format log records.
23
228
  *
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,SAAS,KAAK,MAAM,CAAC;AAsC1D;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAW9D;AAcD;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,aAqBhC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,SAAS,KAAK,SAAS,OAAO,EAAE,CAAC;AAazE;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,OAAO,EAAE,CA2B7E"}
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,SAAS,KAAK,MAAM,CAAC;AAyC1D;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,SAAS,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,SAAS,CAAC,EACN,oBAAoB,GACpB,cAAc,GACd,WAAW,GACX,eAAe,GACf,SAAS,GACT,MAAM,GACN,MAAM,GACN,SAAS,GACT,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAE7B;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,EACF,MAAM,GACN,MAAM,GACN,GAAG,GACH,MAAM,GACN,MAAM,GACN,GAAG,GACH,CAAC,CAAC,KAAK,EAAE,QAAQ,KAAK,MAAM,CAAC,CAAC;IAElC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC,CAAC;IAE9D;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;IAEnC;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,MAAM,CAAC;CAC9C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,oBAAyB,GACjC,aAAa,CA+Df;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,EAAE,aAAkC,CAAC;AAItE;;;GAGG;AACH,MAAM,MAAM,SAAS,GACjB,OAAO,GACP,KAAK,GACL,OAAO,GACP,QAAQ,GACR,MAAM,GACN,SAAS,GACT,MAAM,GACN,OAAO,CAAC;AAaZ;;;GAGG;AACH,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,KAAK,GACL,QAAQ,GACR,WAAW,GACX,eAAe,CAAC;AAkBpB;;;GAGG;AACH,MAAM,WAAW,yBAA0B,SAAQ,oBAAoB;IACrE;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,SAAS,CAAC,EACN,oBAAoB,GACpB,cAAc,GACd,WAAW,GACX,eAAe,GACf,SAAS,GACT,MAAM,GACN,MAAM,GACN,SAAS,GACT,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAE7B;;OAEG;IACH,cAAc,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAElC;;OAEG;IACH,cAAc,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAElC;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAE9B;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC;IAEjD;;OAEG;IACH,aAAa,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAEjC;;OAEG;IACH,aAAa,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,yBAA8B,GACtC,aAAa,CAiDf;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,aAAuC,CAAC;AAEzE;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,SAAS,KAAK,SAAS,OAAO,EAAE,CAAC;AAazE;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,OAAO,EAAE,CA2B7E"}
package/types/mod.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { type Config, ConfigError, configure, dispose, getConfig, type LoggerConfig, reset, } from "./config.js";
2
2
  export { getFileSink, getRotatingFileSink } from "./filesink.node.js";
3
3
  export { type Filter, type FilterLike, getLevelFilter, toFilter, } from "./filter.js";
4
- export { ansiColorFormatter, type ConsoleFormatter, defaultConsoleFormatter, defaultTextFormatter, type TextFormatter, } from "./formatter.js";
4
+ export { type AnsiColor, ansiColorFormatter, type AnsiColorFormatterOptions, type AnsiStyle, type ConsoleFormatter, defaultConsoleFormatter, defaultTextFormatter, type FormattedValues, getAnsiColorFormatter, getTextFormatter, type TextFormatter, type TextFormatterOptions, } from "./formatter.js";
5
5
  export { isLogLevel, type LogLevel, parseLogLevel } from "./level.js";
6
6
  export { getLogger, type Logger } from "./logger.js";
7
7
  export type { LogRecord } from "./record.js";
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,EACX,WAAW,EACX,SAAS,EACT,OAAO,EACP,SAAS,EACT,KAAK,YAAY,EACjB,KAAK,GACN,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EACL,KAAK,MAAM,EACX,KAAK,UAAU,EACf,cAAc,EACd,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,aAAa,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,KAAK,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AACrD,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,cAAc,EACd,aAAa,EACb,KAAK,uBAAuB,EAC5B,KAAK,IAAI,EACT,KAAK,iBAAiB,EACtB,UAAU,GACX,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,EACX,WAAW,EACX,SAAS,EACT,OAAO,EACP,SAAS,EACT,KAAK,YAAY,EACjB,KAAK,GACN,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EACL,KAAK,MAAM,EACX,KAAK,UAAU,EACf,cAAc,EACd,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,SAAS,EACd,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,eAAe,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,aAAa,EAClB,KAAK,oBAAoB,GAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,KAAK,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AACrD,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,cAAc,EACd,aAAa,EACb,KAAK,uBAAuB,EAC5B,KAAK,IAAI,EACT,KAAK,iBAAiB,EACtB,UAAU,GACX,MAAM,WAAW,CAAC"}