@holz/ansi-terminal-backend 0.7.0-rc.2 → 0.8.0-rc.1
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/holz-ansi-terminal-backend.cjs +1 -1
- package/dist/holz-ansi-terminal-backend.d.ts +1 -1
- package/dist/holz-ansi-terminal-backend.js +25 -29
- package/package.json +5 -5
- package/src/__tests__/ansi-terminal-backend.test.ts +8 -4
- package/src/ansi-codes.ts +1 -3
- package/src/ansi-terminal-backend.ts +14 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("@holz/core"),o=t=>`\x1B[${t}`,e=o("0m"),p=o("1m"),$=o("2m"),d=o("31m"),S=o("32m"),v=o("33m"),b=o("34m"),f=o("36m"),A=(t={})=>{const r=t.console??console,l=" ".repeat(5);return n=>{const a=T(new Date),i=`${e}${$}${a}${e}`,m=[{include:!0,command:"%s",content:i},{include:!0,command:"%s",content:y[n.level]},{include:!0,command:"%s",content:n.message.replace(/(\r?\n)/g,`$1${i} ${l} `)},{include:Object.keys(n.context).length>0,command:"%O",content:n.context},{include:n.origin.length>0,command:"%s",content:`${$}${n.origin.join(":")}${e}`}].filter(s=>s.include),u=m.map(s=>s.command).join(" "),g=m.map(s=>s.content);r.error(u,...g)}},T=t=>{const r=t.getHours().toString().padStart(2,"0"),l=t.getMinutes().toString().padStart(2,"0"),n=t.getSeconds().toString().padStart(2,"0"),a=t.getMilliseconds().toString().padStart(3,"0");return`[${r}:${l}:${n}.${a}]`},y={[c.level.trace]:`${f}TRACE${e}`,[c.level.debug]:`${b}DEBUG${e}`,[c.level.info]:`${S}INFO${e} `,[c.level.warn]:`${v}WARN${e} `,[c.level.error]:`${d}ERROR${e}`,[c.level.fatal]:`${p}${d}FATAL${e}`};exports.createAnsiTerminalBackend=A;
|
|
@@ -9,7 +9,7 @@ import { LogProcessor } from '@holz/core';
|
|
|
9
9
|
* ques, the printed text is much less understandable. It is better to check
|
|
10
10
|
* when constructing the logger instead.
|
|
11
11
|
*/
|
|
12
|
-
export declare
|
|
12
|
+
export declare const createAnsiTerminalBackend: (options?: Options) => LogProcessor;
|
|
13
13
|
|
|
14
14
|
declare interface Options {
|
|
15
15
|
/**
|
|
@@ -1,53 +1,49 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
function v(t = {}) {
|
|
7
|
-
const r = t.console ?? console, i = " ".repeat(s.Error.length);
|
|
8
|
-
return (n) => {
|
|
9
|
-
const m = b(/* @__PURE__ */ new Date()), a = `${e}${u}${m}${e}`, l = [
|
|
1
|
+
import { level as c } from "@holz/core";
|
|
2
|
+
const o = (n) => `\x1B[${n}`, t = o("0m"), g = o("1m"), l = o("2m"), d = o("31m"), S = o("32m"), f = o("33m"), b = o("34m"), A = o("36m"), v = (n = {}) => {
|
|
3
|
+
const r = n.console ?? console, m = " ".repeat(5);
|
|
4
|
+
return (e) => {
|
|
5
|
+
const a = x(/* @__PURE__ */ new Date()), i = `${t}${l}${a}${t}`, $ = [
|
|
10
6
|
{
|
|
11
7
|
include: !0,
|
|
12
8
|
command: "%s",
|
|
13
|
-
content:
|
|
9
|
+
content: i
|
|
14
10
|
},
|
|
15
11
|
{
|
|
16
12
|
include: !0,
|
|
17
13
|
command: "%s",
|
|
18
|
-
content:
|
|
14
|
+
content: R[e.level]
|
|
19
15
|
},
|
|
20
16
|
{
|
|
21
17
|
include: !0,
|
|
22
18
|
command: "%s",
|
|
23
|
-
content:
|
|
19
|
+
content: e.message.replace(
|
|
24
20
|
/(\r?\n)/g,
|
|
25
|
-
`$1${
|
|
21
|
+
`$1${i} ${m} `
|
|
26
22
|
)
|
|
27
23
|
},
|
|
28
24
|
{
|
|
29
|
-
include: Object.keys(
|
|
25
|
+
include: Object.keys(e.context).length > 0,
|
|
30
26
|
command: "%O",
|
|
31
|
-
content:
|
|
27
|
+
content: e.context
|
|
32
28
|
},
|
|
33
29
|
{
|
|
34
|
-
include:
|
|
30
|
+
include: e.origin.length > 0,
|
|
35
31
|
command: "%s",
|
|
36
|
-
content: `${
|
|
32
|
+
content: `${l}${e.origin.join(":")}${t}`
|
|
37
33
|
}
|
|
38
|
-
].filter((
|
|
39
|
-
r.error(
|
|
34
|
+
].filter((s) => s.include), u = $.map((s) => s.command).join(" "), p = $.map((s) => s.content);
|
|
35
|
+
r.error(u, ...p);
|
|
40
36
|
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
[
|
|
48
|
-
[
|
|
49
|
-
[
|
|
50
|
-
[
|
|
37
|
+
}, x = (n) => {
|
|
38
|
+
const r = n.getHours().toString().padStart(2, "0"), m = n.getMinutes().toString().padStart(2, "0"), e = n.getSeconds().toString().padStart(2, "0"), a = n.getMilliseconds().toString().padStart(3, "0");
|
|
39
|
+
return `[${r}:${m}:${e}.${a}]`;
|
|
40
|
+
}, R = {
|
|
41
|
+
[c.trace]: `${A}TRACE${t}`,
|
|
42
|
+
[c.debug]: `${b}DEBUG${t}`,
|
|
43
|
+
[c.info]: `${S}INFO${t} `,
|
|
44
|
+
[c.warn]: `${f}WARN${t} `,
|
|
45
|
+
[c.error]: `${d}ERROR${t}`,
|
|
46
|
+
[c.fatal]: `${g}${d}FATAL${t}`
|
|
51
47
|
};
|
|
52
48
|
export {
|
|
53
49
|
v as createAnsiTerminalBackend
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holz/ansi-terminal-backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0-rc.1",
|
|
4
4
|
"description": "An ANSI terminal backend for Holz",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -36,17 +36,17 @@
|
|
|
36
36
|
"test:types": "tsc"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@holz/core": "^0.
|
|
39
|
+
"@holz/core": "^0.8.0-rc.1"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@holz/core": "^0.
|
|
42
|
+
"@holz/core": "^0.8.0-rc.1",
|
|
43
43
|
"@types/node": "^22.0.0",
|
|
44
44
|
"@vitest/coverage-v8": "^3.0.8",
|
|
45
|
-
"typescript": "^5.
|
|
45
|
+
"typescript": "^5.8.2",
|
|
46
46
|
"vite": "^6.0.0",
|
|
47
47
|
"vite-plugin-dts": "^4.5.3",
|
|
48
48
|
"vite-tsconfig-paths": "^5.1.4",
|
|
49
49
|
"vitest": "^3.0.8"
|
|
50
50
|
},
|
|
51
|
-
"stableVersion": "0.
|
|
51
|
+
"stableVersion": "0.7.0"
|
|
52
52
|
}
|
|
@@ -6,7 +6,7 @@ import { createAnsiTerminalBackend } from '../ansi-terminal-backend';
|
|
|
6
6
|
const CURRENT_TIME = new Date('2020-06-15T03:05:07.010Z');
|
|
7
7
|
|
|
8
8
|
describe('ANSI terminal backend', () => {
|
|
9
|
-
|
|
9
|
+
const createStream = () => {
|
|
10
10
|
let output = '';
|
|
11
11
|
const stream = new Writable({
|
|
12
12
|
write(chunk, _encoding, callback) {
|
|
@@ -19,10 +19,10 @@ describe('ANSI terminal backend', () => {
|
|
|
19
19
|
getOutput: () => output,
|
|
20
20
|
stream,
|
|
21
21
|
};
|
|
22
|
-
}
|
|
22
|
+
};
|
|
23
23
|
|
|
24
24
|
// Named "terminal" to avoid conflict with `global.console`.
|
|
25
|
-
|
|
25
|
+
const createTerminal = () => {
|
|
26
26
|
const stdout = createStream();
|
|
27
27
|
const stderr = createStream();
|
|
28
28
|
const terminal = new Console({
|
|
@@ -35,7 +35,7 @@ describe('ANSI terminal backend', () => {
|
|
|
35
35
|
stderr,
|
|
36
36
|
terminal,
|
|
37
37
|
};
|
|
38
|
-
}
|
|
38
|
+
};
|
|
39
39
|
|
|
40
40
|
beforeEach(() => {
|
|
41
41
|
vi.useFakeTimers({
|
|
@@ -62,15 +62,19 @@ describe('ANSI terminal backend', () => {
|
|
|
62
62
|
const backend = createAnsiTerminalBackend({ console: terminal });
|
|
63
63
|
|
|
64
64
|
const logger = createLogger(backend);
|
|
65
|
+
logger.trace('scream');
|
|
65
66
|
logger.debug('shout');
|
|
66
67
|
logger.info('normal');
|
|
67
68
|
logger.warn('hmmmm');
|
|
68
69
|
logger.error('oh no');
|
|
70
|
+
logger.fatal('goodbye');
|
|
69
71
|
|
|
72
|
+
expect(stderr.getOutput()).toContain('TRACE');
|
|
70
73
|
expect(stderr.getOutput()).toContain('DEBUG');
|
|
71
74
|
expect(stderr.getOutput()).toContain('INFO');
|
|
72
75
|
expect(stderr.getOutput()).toContain('WARN');
|
|
73
76
|
expect(stderr.getOutput()).toContain('ERROR');
|
|
77
|
+
expect(stderr.getOutput()).toContain('FATAL');
|
|
74
78
|
});
|
|
75
79
|
|
|
76
80
|
it('includes the log namespace', () => {
|
package/src/ansi-codes.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { LogLevel } from '@holz/core';
|
|
1
|
+
import { level, type LogLevel, type Log, type LogProcessor } from '@holz/core';
|
|
3
2
|
import * as ansi from './ansi-codes';
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -11,9 +10,11 @@ import * as ansi from './ansi-codes';
|
|
|
11
10
|
* ques, the printed text is much less understandable. It is better to check
|
|
12
11
|
* when constructing the logger instead.
|
|
13
12
|
*/
|
|
14
|
-
export
|
|
13
|
+
export const createAnsiTerminalBackend = (
|
|
14
|
+
options: Options = {},
|
|
15
|
+
): LogProcessor => {
|
|
15
16
|
const output = options.console ?? console;
|
|
16
|
-
const labelSizeInWhitespace = ' '.repeat(
|
|
17
|
+
const labelSizeInWhitespace = ' '.repeat(5); // char length of longest level type
|
|
17
18
|
|
|
18
19
|
return (log: Log) => {
|
|
19
20
|
const timestamp = formatAsTimestamp(new Date());
|
|
@@ -55,24 +56,26 @@ export function createAnsiTerminalBackend(options: Options = {}): LogProcessor {
|
|
|
55
56
|
// CLIs typically print interactive messages to stdout and logs to stderr.
|
|
56
57
|
output.error(format, ...values);
|
|
57
58
|
};
|
|
58
|
-
}
|
|
59
|
+
};
|
|
59
60
|
|
|
60
61
|
// ISO-8601 timestamp with milliseconds.
|
|
61
|
-
|
|
62
|
+
const formatAsTimestamp = (date: Date) => {
|
|
62
63
|
const hours = date.getHours().toString().padStart(2, '0');
|
|
63
64
|
const minutes = date.getMinutes().toString().padStart(2, '0');
|
|
64
65
|
const seconds = date.getSeconds().toString().padStart(2, '0');
|
|
65
66
|
const milliseconds = date.getMilliseconds().toString().padStart(3, '0');
|
|
66
67
|
|
|
67
68
|
return `[${hours}:${minutes}:${seconds}.${milliseconds}]`;
|
|
68
|
-
}
|
|
69
|
+
};
|
|
69
70
|
|
|
70
71
|
// Trailing whitespace is important for alignment.
|
|
71
72
|
const logLevelLabel: Record<LogLevel, string> = {
|
|
72
|
-
[
|
|
73
|
-
[
|
|
74
|
-
[
|
|
75
|
-
[
|
|
73
|
+
[level.trace]: `${ansi.cyan}TRACE${ansi.reset}`,
|
|
74
|
+
[level.debug]: `${ansi.blue}DEBUG${ansi.reset}`,
|
|
75
|
+
[level.info]: `${ansi.green}INFO${ansi.reset} `,
|
|
76
|
+
[level.warn]: `${ansi.yellow}WARN${ansi.reset} `,
|
|
77
|
+
[level.error]: `${ansi.red}ERROR${ansi.reset}`,
|
|
78
|
+
[level.fatal]: `${ansi.bold}${ansi.red}FATAL${ansi.reset}`,
|
|
76
79
|
};
|
|
77
80
|
|
|
78
81
|
interface Options {
|