@logtape/pretty 1.0.0-dev.231 β 1.0.0-dev.232
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 +167 -92
- package/deno.json +1 -1
- package/dist/formatter.cjs +76 -82
- package/dist/formatter.d.cts +23 -23
- package/dist/formatter.d.cts.map +1 -1
- package/dist/formatter.d.ts +23 -23
- package/dist/formatter.d.ts.map +1 -1
- package/dist/formatter.js +76 -82
- package/dist/formatter.js.map +1 -1
- package/dist/wcwidth.cjs +193 -2
- package/dist/wcwidth.js +193 -2
- package/dist/wcwidth.js.map +1 -1
- package/formatter.test.ts +24 -2
- package/formatter.ts +117 -128
- package/package.json +3 -3
- package/wcwidth.ts +210 -179
package/README.md
CHANGED
|
@@ -1,44 +1,55 @@
|
|
|
1
|
-
|
|
1
|
+
<!-- deno-fmt-ignore-file -->
|
|
2
2
|
|
|
3
|
-
Beautiful
|
|
3
|
+
Beautiful text formatter for LogTape
|
|
4
|
+
====================================
|
|
4
5
|
|
|
5
|
-
[
|
|
6
|
+
[![JSR][JSR badge]][JSR]
|
|
7
|
+
[![npm][npm badge]][npm]
|
|
6
8
|
|
|
7
|
-
[LogTape]
|
|
8
|
-
[
|
|
9
|
+
Beautiful text formatter for [LogTape]βperfect for local development!
|
|
10
|
+
This package provides a visually appealing formatter inspired by [Signale],
|
|
11
|
+
designed to make your development logs easier to read and debug.
|
|
12
|
+
|
|
13
|
+
[JSR]: https://jsr.io/@logtape/pretty
|
|
14
|
+
[JSR badge]: https://jsr.io/badges/@logtape/pretty
|
|
15
|
+
[npm]: https://www.npmjs.com/package/@logtape/pretty
|
|
16
|
+
[npm badge]: https://img.shields.io/npm/v/@logtape/pretty?logo=npm
|
|
17
|
+
[LogTape]: https://logtape.org/
|
|
9
18
|
[Signale]: https://github.com/klaudiosinani/signale
|
|
10
19
|
|
|
11
|
-
## Features
|
|
12
20
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- βοΈ **Smart Truncation**: Intelligent category truncation to maintain layout
|
|
16
|
-
- π **Perfect Alignment**: Columns align beautifully for easy scanning
|
|
17
|
-
- π― **Development Focused**: Optimized for local development experience
|
|
18
|
-
- π **Zero Dependencies**: Lightweight and fast
|
|
21
|
+
Features
|
|
22
|
+
--------
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
- *Beautiful design*: Inspired by Signale with colorful icons and clean layout
|
|
25
|
+
- *True color support*: Rich colors for modern terminals
|
|
26
|
+
- *Smart truncation*: Intelligent category truncation to maintain layout
|
|
27
|
+
- *Perfect alignment*: Columns align beautifully for easy scanning
|
|
28
|
+
- *Development focused*: Optimized for local development experience
|
|
29
|
+
- *Word wrapping*: Automatic text wrapping with proper indentation
|
|
30
|
+
- *Zero dependencies*: Lightweight and fast
|
|
21
31
|
|
|
22
|
-
### Deno
|
|
23
|
-
```typescript
|
|
24
|
-
import { prettyFormatter } from "@logtape/pretty";
|
|
25
|
-
```
|
|
26
32
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
npm install @logtape/pretty
|
|
30
|
-
```
|
|
33
|
+
Installation
|
|
34
|
+
------------
|
|
31
35
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
bun add @logtape/pretty
|
|
35
|
-
```
|
|
36
|
+
This package is available on [JSR] and [npm]. You can install it for various
|
|
37
|
+
JavaScript runtimes and package managers:
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
~~~~ sh
|
|
40
|
+
deno add jsr:@logtape/pretty # for Deno
|
|
41
|
+
npm add @logtape/pretty # for npm
|
|
42
|
+
pnpm add @logtape/pretty # for pnpm
|
|
43
|
+
yarn add @logtape/pretty # for Yarn
|
|
44
|
+
bun add @logtape/pretty # for Bun
|
|
45
|
+
~~~~
|
|
38
46
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
|
|
48
|
+
Quick start
|
|
49
|
+
-----------
|
|
50
|
+
|
|
51
|
+
~~~~ typescript
|
|
52
|
+
import { configure, getConsoleSink, getLogger } from "@logtape/logtape";
|
|
42
53
|
import { prettyFormatter } from "@logtape/pretty";
|
|
43
54
|
|
|
44
55
|
await configure({
|
|
@@ -48,11 +59,7 @@ await configure({
|
|
|
48
59
|
})
|
|
49
60
|
},
|
|
50
61
|
loggers: [
|
|
51
|
-
{
|
|
52
|
-
category: "my-app",
|
|
53
|
-
level: "debug",
|
|
54
|
-
sinks: ["console"]
|
|
55
|
-
}
|
|
62
|
+
{ category: "my-app", lowestLevel: "debug", sinks: ["console"] }
|
|
56
63
|
]
|
|
57
64
|
});
|
|
58
65
|
|
|
@@ -62,68 +69,77 @@ logger.info`Server started on port ${3000}`;
|
|
|
62
69
|
logger.debug`Connected to database`;
|
|
63
70
|
logger.warn`Cache size exceeding 80% capacity`;
|
|
64
71
|
logger.error`Failed to process request: ${{ error: "timeout" }}`;
|
|
65
|
-
|
|
72
|
+
~~~~
|
|
73
|
+
|
|
74
|
+
Output example:
|
|
66
75
|
|
|
67
|
-
|
|
76
|
+

|
|
68
77
|
|
|
69
|
-
|
|
70
|
-
β¨ info my-app
|
|
71
|
-
π debug my-app
|
|
72
|
-
|
|
73
|
-
β error my-app
|
|
74
|
-
|
|
78
|
+
~~~~
|
|
79
|
+
β¨ info my-app Server started on port 3000
|
|
80
|
+
π debug my-app Connected to database
|
|
81
|
+
β‘ warning my-app Cache size exceeding 80% capacity
|
|
82
|
+
β error my-app Failed to process request: { error: 'timeout' }
|
|
83
|
+
~~~~
|
|
75
84
|
|
|
76
|
-
## Configuration
|
|
77
85
|
|
|
78
|
-
|
|
86
|
+
Configuration
|
|
87
|
+
-------------
|
|
79
88
|
|
|
80
|
-
|
|
89
|
+
### Basic options
|
|
90
|
+
|
|
91
|
+
~~~~ typescript
|
|
81
92
|
import { getPrettyFormatter } from "@logtape/pretty";
|
|
82
93
|
|
|
83
94
|
const formatter = getPrettyFormatter({
|
|
84
95
|
// Show timestamp
|
|
85
|
-
timestamp: "time", // "time" | "
|
|
86
|
-
|
|
96
|
+
timestamp: "time", // "time" | "date-time" | "date" | "rfc3339" | etc.
|
|
97
|
+
|
|
87
98
|
// Customize icons
|
|
88
99
|
icons: {
|
|
89
|
-
info: "βΉοΈ
|
|
100
|
+
info: "βΉοΈ",
|
|
90
101
|
error: "π₯"
|
|
91
102
|
},
|
|
92
|
-
|
|
103
|
+
|
|
93
104
|
// Control colors
|
|
94
105
|
colors: true,
|
|
95
|
-
|
|
96
|
-
dimCategory: true,
|
|
97
|
-
|
|
106
|
+
|
|
98
107
|
// Category display
|
|
99
108
|
categoryWidth: 20,
|
|
100
|
-
categoryTruncate: "middle" // "middle" | "end" | false
|
|
109
|
+
categoryTruncate: "middle", // "middle" | "end" | false
|
|
110
|
+
|
|
111
|
+
// Word wrapping
|
|
112
|
+
wordWrap: true // true | false | number
|
|
101
113
|
});
|
|
102
|
-
|
|
114
|
+
~~~~
|
|
103
115
|
|
|
104
|
-
### Timestamp
|
|
116
|
+
### Timestamp options
|
|
105
117
|
|
|
106
|
-
|
|
118
|
+
~~~~ typescript
|
|
107
119
|
// No timestamp (default)
|
|
108
|
-
getPrettyFormatter({ timestamp:
|
|
120
|
+
getPrettyFormatter({ timestamp: "none" })
|
|
109
121
|
|
|
110
122
|
// Time only (HH:MM:SS)
|
|
111
123
|
getPrettyFormatter({ timestamp: "time" })
|
|
112
124
|
// Output: 12:34:56 β¨ info app Message
|
|
113
125
|
|
|
114
126
|
// Date and time
|
|
115
|
-
getPrettyFormatter({ timestamp: "
|
|
127
|
+
getPrettyFormatter({ timestamp: "date-time" })
|
|
116
128
|
// Output: 2024-01-15 12:34:56 β¨ info app Message
|
|
117
129
|
|
|
130
|
+
// RFC 3339 format
|
|
131
|
+
getPrettyFormatter({ timestamp: "rfc3339" })
|
|
132
|
+
// Output: 2024-01-15T12:34:56.789Z β¨ info app Message
|
|
133
|
+
|
|
118
134
|
// Custom formatter
|
|
119
|
-
getPrettyFormatter({
|
|
135
|
+
getPrettyFormatter({
|
|
120
136
|
timestamp: (ts) => new Date(ts).toLocaleTimeString()
|
|
121
137
|
})
|
|
122
|
-
|
|
138
|
+
~~~~
|
|
123
139
|
|
|
124
|
-
### Icon
|
|
140
|
+
### Icon customization
|
|
125
141
|
|
|
126
|
-
|
|
142
|
+
~~~~ typescript
|
|
127
143
|
// Disable all icons
|
|
128
144
|
getPrettyFormatter({ icons: false })
|
|
129
145
|
|
|
@@ -133,7 +149,7 @@ getPrettyFormatter({
|
|
|
133
149
|
info: "π",
|
|
134
150
|
warning: "πΆ",
|
|
135
151
|
error: "π¨",
|
|
136
|
-
fatal: "β οΈ
|
|
152
|
+
fatal: "β οΈ"
|
|
137
153
|
}
|
|
138
154
|
})
|
|
139
155
|
|
|
@@ -141,54 +157,110 @@ getPrettyFormatter({
|
|
|
141
157
|
// trace: π
|
|
142
158
|
// debug: π
|
|
143
159
|
// info: β¨
|
|
144
|
-
// warning:
|
|
160
|
+
// warning: β‘
|
|
145
161
|
// error: β
|
|
146
162
|
// fatal: π
|
|
147
|
-
|
|
163
|
+
~~~~
|
|
148
164
|
|
|
149
|
-
### Category
|
|
165
|
+
### Category truncation
|
|
150
166
|
|
|
151
|
-
|
|
167
|
+
~~~~ typescript
|
|
152
168
|
// Fixed width with middle truncation (default)
|
|
153
169
|
getPrettyFormatter({
|
|
154
170
|
categoryWidth: 20,
|
|
155
171
|
categoryTruncate: "middle"
|
|
156
172
|
})
|
|
157
|
-
// "app
|
|
173
|
+
// "appΒ·serverΒ·httpΒ·middleware" β "appβ¦middleware"
|
|
158
174
|
|
|
159
175
|
// End truncation
|
|
160
176
|
getPrettyFormatter({
|
|
161
177
|
categoryWidth: 20,
|
|
162
178
|
categoryTruncate: "end"
|
|
163
179
|
})
|
|
164
|
-
// "app
|
|
180
|
+
// "appΒ·serverΒ·httpΒ·middleware" β "appΒ·serverΒ·httpβ¦"
|
|
165
181
|
|
|
166
182
|
// No truncation
|
|
167
183
|
getPrettyFormatter({
|
|
168
184
|
categoryTruncate: false
|
|
169
185
|
})
|
|
170
|
-
```
|
|
171
186
|
|
|
172
|
-
|
|
187
|
+
// Custom category separator
|
|
188
|
+
getPrettyFormatter({
|
|
189
|
+
categorySeparator: "." // Default is "Β·"
|
|
190
|
+
})
|
|
191
|
+
~~~~
|
|
173
192
|
|
|
174
|
-
|
|
193
|
+
### Color and style control
|
|
194
|
+
|
|
195
|
+
~~~~ typescript
|
|
175
196
|
// Disable colors (for CI/CD environments)
|
|
176
197
|
getPrettyFormatter({ colors: false })
|
|
177
198
|
|
|
178
|
-
//
|
|
199
|
+
// Customize colors
|
|
179
200
|
getPrettyFormatter({
|
|
180
|
-
|
|
181
|
-
|
|
201
|
+
timestampColor: "#888888",
|
|
202
|
+
levelColors: {
|
|
203
|
+
info: "#00ff00",
|
|
204
|
+
error: "#ff0000"
|
|
205
|
+
},
|
|
206
|
+
categoryColor: "rgb(100,150,200)",
|
|
207
|
+
messageColor: "#ffffff"
|
|
182
208
|
})
|
|
183
|
-
```
|
|
184
209
|
|
|
185
|
-
|
|
210
|
+
// Apply styles
|
|
211
|
+
getPrettyFormatter({
|
|
212
|
+
timestampStyle: "dim",
|
|
213
|
+
levelStyle: ["bold", "underline"],
|
|
214
|
+
categoryStyle: ["dim", "italic"],
|
|
215
|
+
messageStyle: "dim"
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
// Category color mapping
|
|
219
|
+
getPrettyFormatter({
|
|
220
|
+
categoryColorMap: new Map([
|
|
221
|
+
[["app", "auth"], "#ff6b6b"], // appΒ·authΒ·* -> red
|
|
222
|
+
[["app", "db"], "#4ecdc4"], // appΒ·dbΒ·* -> teal
|
|
223
|
+
[["app"], "#45b7d1"], // appΒ·* (fallback) -> blue
|
|
224
|
+
[["lib"], "#96ceb4"], // libΒ·* -> green
|
|
225
|
+
])
|
|
226
|
+
})
|
|
227
|
+
~~~~
|
|
228
|
+
|
|
229
|
+
### Word wrapping
|
|
230
|
+
|
|
231
|
+
~~~~ typescript
|
|
232
|
+
// Auto-detect terminal width
|
|
233
|
+
getPrettyFormatter({ wordWrap: true })
|
|
234
|
+
|
|
235
|
+
// Custom wrap width
|
|
236
|
+
getPrettyFormatter({ wordWrap: 120 })
|
|
237
|
+
|
|
238
|
+
// Disable word wrapping
|
|
239
|
+
getPrettyFormatter({ wordWrap: false })
|
|
240
|
+
~~~~
|
|
186
241
|
|
|
187
|
-
###
|
|
242
|
+
### Inspect options
|
|
243
|
+
|
|
244
|
+
~~~~ typescript
|
|
245
|
+
// Control how objects are displayed
|
|
246
|
+
getPrettyFormatter({
|
|
247
|
+
inspectOptions: {
|
|
248
|
+
depth: 3, // Show 3 levels of nesting
|
|
249
|
+
colors: false, // Disable value syntax highlighting
|
|
250
|
+
compact: true, // Use compact object display
|
|
251
|
+
}
|
|
252
|
+
})
|
|
253
|
+
~~~~
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
Advanced usage
|
|
257
|
+
--------------
|
|
258
|
+
|
|
259
|
+
### Multiple formatters
|
|
188
260
|
|
|
189
261
|
Use different formatters for different environments:
|
|
190
262
|
|
|
191
|
-
|
|
263
|
+
~~~~ typescript
|
|
192
264
|
import { configure } from "@logtape/logtape";
|
|
193
265
|
import { getConsoleSink } from "@logtape/logtape/sink";
|
|
194
266
|
import { prettyFormatter } from "@logtape/pretty";
|
|
@@ -203,34 +275,37 @@ await configure({
|
|
|
203
275
|
})
|
|
204
276
|
}
|
|
205
277
|
});
|
|
206
|
-
|
|
278
|
+
~~~~
|
|
207
279
|
|
|
208
|
-
### CI/CD
|
|
280
|
+
### CI/CD friendly
|
|
209
281
|
|
|
210
282
|
Automatically detect CI environments and adjust:
|
|
211
283
|
|
|
212
|
-
|
|
284
|
+
~~~~ typescript
|
|
213
285
|
const isCI = process.env.CI === "true";
|
|
214
286
|
|
|
215
287
|
const formatter = getPrettyFormatter({
|
|
216
288
|
colors: !isCI,
|
|
217
289
|
icons: !isCI,
|
|
218
|
-
timestamp: isCI ? "
|
|
290
|
+
timestamp: isCI ? "date-time" : "none"
|
|
219
291
|
});
|
|
220
|
-
|
|
292
|
+
~~~~
|
|
293
|
+
|
|
221
294
|
|
|
222
|
-
|
|
295
|
+
Design philosophy
|
|
296
|
+
-----------------
|
|
223
297
|
|
|
224
298
|
@logtape/pretty is designed specifically for local development, prioritizing:
|
|
225
299
|
|
|
226
|
-
-
|
|
227
|
-
-
|
|
228
|
-
-
|
|
300
|
+
- *Visual clarity*: Easy to scan and find important information
|
|
301
|
+
- *Minimal noise*: Only show what's necessary
|
|
302
|
+
- *Developer joy*: Make logs beautiful and enjoyable to read
|
|
229
303
|
|
|
230
|
-
## License
|
|
231
304
|
|
|
232
|
-
|
|
305
|
+
Docs
|
|
306
|
+
----
|
|
233
307
|
|
|
234
|
-
|
|
308
|
+
For detailed documentation, see the [pretty formatter manual]. For the API
|
|
309
|
+
references, see <https://jsr.io/@logtape/pretty>.
|
|
235
310
|
|
|
236
|
-
|
|
311
|
+
[pretty formatter manual]: https://logtape.org/manual/formatters#pretty-formatter
|
package/deno.json
CHANGED
package/dist/formatter.cjs
CHANGED
|
@@ -46,18 +46,20 @@ const ansiColors = {
|
|
|
46
46
|
cyan: "\x1B[36m",
|
|
47
47
|
white: "\x1B[37m"
|
|
48
48
|
};
|
|
49
|
+
const RGB_PATTERN = /^rgb\((\d+),(\d+),(\d+)\)$/;
|
|
50
|
+
const HEX_PATTERN = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
49
51
|
/**
|
|
50
52
|
* Helper function to convert color to ANSI escape code
|
|
51
53
|
*/
|
|
52
54
|
function colorToAnsi(color) {
|
|
53
55
|
if (color === null) return "";
|
|
54
56
|
if (color in ansiColors) return ansiColors[color];
|
|
55
|
-
const rgbMatch = color.match(
|
|
57
|
+
const rgbMatch = color.match(RGB_PATTERN);
|
|
56
58
|
if (rgbMatch) {
|
|
57
59
|
const [, r, g, b] = rgbMatch;
|
|
58
60
|
return `\x1b[38;2;${r};${g};${b}m`;
|
|
59
61
|
}
|
|
60
|
-
const hexMatch = color.match(
|
|
62
|
+
const hexMatch = color.match(HEX_PATTERN);
|
|
61
63
|
if (hexMatch) {
|
|
62
64
|
let hex = hexMatch[1];
|
|
63
65
|
if (hex.length === 3) hex = hex.split("").map((c) => c + c).join("");
|
|
@@ -126,14 +128,9 @@ const defaultIcons = {
|
|
|
126
128
|
* @returns A new icon map with consistent spacing
|
|
127
129
|
*/
|
|
128
130
|
function normalizeIconSpacing(iconMap) {
|
|
129
|
-
const
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
const currentWidth = require_wcwidth.getDisplayWidth(icon);
|
|
133
|
-
const spacesToAdd = maxWidth - currentWidth;
|
|
134
|
-
normalizedMap[level] = icon + " ".repeat(spacesToAdd);
|
|
135
|
-
}
|
|
136
|
-
return normalizedMap;
|
|
131
|
+
const entries = Object.entries(iconMap);
|
|
132
|
+
const maxWidth = Math.max(...entries.map(([, icon]) => require_wcwidth.getDisplayWidth(icon)));
|
|
133
|
+
return Object.fromEntries(entries.map(([level, icon]) => [level, icon + " ".repeat(maxWidth - require_wcwidth.getDisplayWidth(icon))]));
|
|
137
134
|
}
|
|
138
135
|
/**
|
|
139
136
|
* Platform-specific inspect function. Uses Node.js `util.inspect()` which
|
|
@@ -172,7 +169,7 @@ const inspect = typeof document !== "undefined" || typeof navigator !== "undefin
|
|
|
172
169
|
* @example
|
|
173
170
|
* ```typescript
|
|
174
171
|
* import { configure } from "@logtape/logtape";
|
|
175
|
-
* import { getConsoleSink } from "@logtape/logtape";
|
|
172
|
+
* import { getConsoleSink } from "@logtape/logtape/sink";
|
|
176
173
|
* import { getPrettyFormatter } from "@logtape/pretty";
|
|
177
174
|
*
|
|
178
175
|
* await configure({
|
|
@@ -194,7 +191,7 @@ const inspect = typeof document !== "undefined" || typeof navigator !== "undefin
|
|
|
194
191
|
* @since 1.0.0
|
|
195
192
|
*/
|
|
196
193
|
function getPrettyFormatter(options = {}) {
|
|
197
|
-
const { timestamp = "none", timestampColor = "rgb(100,116,139)", timestampStyle = "dim", level: levelFormat = "full", levelColors = {}, levelStyle = "underline", icons = true, categorySeparator = "Β·", categoryColor = "rgb(100,116,139)", categoryColorMap = /* @__PURE__ */ new Map(), categoryStyle = ["dim", "italic"], categoryWidth = 20, categoryTruncate = "middle", messageColor = "rgb(148,163,184)", messageStyle = "dim", colors: useColors = true, align = true, inspectOptions = {}, wordWrap =
|
|
194
|
+
const { timestamp = "none", timestampColor = "rgb(100,116,139)", timestampStyle = "dim", level: levelFormat = "full", levelColors = {}, levelStyle = "underline", icons = true, categorySeparator = "Β·", categoryColor = "rgb(100,116,139)", categoryColorMap = /* @__PURE__ */ new Map(), categoryStyle = ["dim", "italic"], categoryWidth = 20, categoryTruncate = "middle", messageColor = "rgb(148,163,184)", messageStyle = "dim", colors: useColors = true, align = true, inspectOptions = {}, wordWrap = true } = options;
|
|
198
195
|
const baseIconMap = icons === false ? {
|
|
199
196
|
trace: "",
|
|
200
197
|
debug: "",
|
|
@@ -216,81 +213,78 @@ function getPrettyFormatter(options = {}) {
|
|
|
216
213
|
fatal: defaultColors.fatal,
|
|
217
214
|
...levelColors
|
|
218
215
|
};
|
|
216
|
+
const levelMappings = {
|
|
217
|
+
"ABBR": {
|
|
218
|
+
trace: "TRC",
|
|
219
|
+
debug: "DBG",
|
|
220
|
+
info: "INF",
|
|
221
|
+
warning: "WRN",
|
|
222
|
+
error: "ERR",
|
|
223
|
+
fatal: "FTL"
|
|
224
|
+
},
|
|
225
|
+
"L": {
|
|
226
|
+
trace: "T",
|
|
227
|
+
debug: "D",
|
|
228
|
+
info: "I",
|
|
229
|
+
warning: "W",
|
|
230
|
+
error: "E",
|
|
231
|
+
fatal: "F"
|
|
232
|
+
},
|
|
233
|
+
"abbr": {
|
|
234
|
+
trace: "trc",
|
|
235
|
+
debug: "dbg",
|
|
236
|
+
info: "inf",
|
|
237
|
+
warning: "wrn",
|
|
238
|
+
error: "err",
|
|
239
|
+
fatal: "ftl"
|
|
240
|
+
},
|
|
241
|
+
"l": {
|
|
242
|
+
trace: "t",
|
|
243
|
+
debug: "d",
|
|
244
|
+
info: "i",
|
|
245
|
+
warning: "w",
|
|
246
|
+
error: "e",
|
|
247
|
+
fatal: "f"
|
|
248
|
+
}
|
|
249
|
+
};
|
|
219
250
|
const formatLevel = (level) => {
|
|
220
251
|
if (typeof levelFormat === "function") return levelFormat(level);
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
warning: "w",
|
|
253
|
-
error: "e",
|
|
254
|
-
fatal: "f"
|
|
255
|
-
}[level];
|
|
256
|
-
default: return level;
|
|
257
|
-
}
|
|
252
|
+
if (levelFormat === "FULL") return level.toUpperCase();
|
|
253
|
+
if (levelFormat === "full") return level;
|
|
254
|
+
return levelMappings[levelFormat]?.[level] ?? level;
|
|
255
|
+
};
|
|
256
|
+
const timestampFormatters = {
|
|
257
|
+
"date-time-timezone": (ts) => {
|
|
258
|
+
const iso = new Date(ts).toISOString();
|
|
259
|
+
return iso.replace("T", " ").replace("Z", " +00:00");
|
|
260
|
+
},
|
|
261
|
+
"date-time-tz": (ts) => {
|
|
262
|
+
const iso = new Date(ts).toISOString();
|
|
263
|
+
return iso.replace("T", " ").replace("Z", " +00");
|
|
264
|
+
},
|
|
265
|
+
"date-time": (ts) => {
|
|
266
|
+
const iso = new Date(ts).toISOString();
|
|
267
|
+
return iso.replace("T", " ").replace("Z", "");
|
|
268
|
+
},
|
|
269
|
+
"time-timezone": (ts) => {
|
|
270
|
+
const iso = new Date(ts).toISOString();
|
|
271
|
+
return iso.replace(/.*T/, "").replace("Z", " +00:00");
|
|
272
|
+
},
|
|
273
|
+
"time-tz": (ts) => {
|
|
274
|
+
const iso = new Date(ts).toISOString();
|
|
275
|
+
return iso.replace(/.*T/, "").replace("Z", " +00");
|
|
276
|
+
},
|
|
277
|
+
"time": (ts) => {
|
|
278
|
+
const iso = new Date(ts).toISOString();
|
|
279
|
+
return iso.replace(/.*T/, "").replace("Z", "");
|
|
280
|
+
},
|
|
281
|
+
"date": (ts) => new Date(ts).toISOString().replace(/T.*/, ""),
|
|
282
|
+
"rfc3339": (ts) => new Date(ts).toISOString()
|
|
258
283
|
};
|
|
259
284
|
let timestampFn = null;
|
|
260
285
|
if (timestamp === "none" || timestamp === "disabled") timestampFn = null;
|
|
261
|
-
else if (timestamp === "date-time-timezone") timestampFn = (ts) => {
|
|
262
|
-
const date = new Date(ts);
|
|
263
|
-
return date.toISOString().replace("T", " ").replace("Z", " +00:00");
|
|
264
|
-
};
|
|
265
|
-
else if (timestamp === "date-time-tz") timestampFn = (ts) => {
|
|
266
|
-
const date = new Date(ts);
|
|
267
|
-
return date.toISOString().replace("T", " ").replace("Z", " +00");
|
|
268
|
-
};
|
|
269
|
-
else if (timestamp === "date-time") timestampFn = (ts) => {
|
|
270
|
-
const date = new Date(ts);
|
|
271
|
-
return date.toISOString().replace("T", " ").replace("Z", "");
|
|
272
|
-
};
|
|
273
|
-
else if (timestamp === "time-timezone") timestampFn = (ts) => {
|
|
274
|
-
const date = new Date(ts);
|
|
275
|
-
return date.toISOString().replace(/.*T/, "").replace("Z", " +00:00");
|
|
276
|
-
};
|
|
277
|
-
else if (timestamp === "time-tz") timestampFn = (ts) => {
|
|
278
|
-
const date = new Date(ts);
|
|
279
|
-
return date.toISOString().replace(/.*T/, "").replace("Z", " +00");
|
|
280
|
-
};
|
|
281
|
-
else if (timestamp === "time") timestampFn = (ts) => {
|
|
282
|
-
const date = new Date(ts);
|
|
283
|
-
return date.toISOString().replace(/.*T/, "").replace("Z", "");
|
|
284
|
-
};
|
|
285
|
-
else if (timestamp === "date") timestampFn = (ts) => {
|
|
286
|
-
const date = new Date(ts);
|
|
287
|
-
return date.toISOString().replace(/T.*/, "");
|
|
288
|
-
};
|
|
289
|
-
else if (timestamp === "rfc3339") timestampFn = (ts) => {
|
|
290
|
-
const date = new Date(ts);
|
|
291
|
-
return date.toISOString();
|
|
292
|
-
};
|
|
293
286
|
else if (typeof timestamp === "function") timestampFn = timestamp;
|
|
287
|
+
else timestampFn = timestampFormatters[timestamp] ?? null;
|
|
294
288
|
const wordWrapEnabled = wordWrap !== false;
|
|
295
289
|
let wordWrapWidth;
|
|
296
290
|
if (typeof wordWrap === "number") wordWrapWidth = wordWrap;
|
|
@@ -391,7 +385,7 @@ function getPrettyFormatter(options = {}) {
|
|
|
391
385
|
* @example
|
|
392
386
|
* ```typescript
|
|
393
387
|
* import { configure } from "@logtape/logtape";
|
|
394
|
-
* import { getConsoleSink } from "@logtape/logtape";
|
|
388
|
+
* import { getConsoleSink } from "@logtape/logtape/sink";
|
|
395
389
|
* import { prettyFormatter } from "@logtape/pretty";
|
|
396
390
|
*
|
|
397
391
|
* await configure({
|