@holz/ansi-terminal-backend 0.0.0 → 0.1.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.
@@ -1,59 +1,68 @@
1
- var t = /* @__PURE__ */ ((r) => (r.Error = "error", r.Warn = "warn", r.Info = "info", r.Debug = "debug", r))(t || {});
2
- function e(r) {
3
- return `\x1B[${r}`;
1
+ var s = /* @__PURE__ */ ((o) => (o.Error = "error", o.Warn = "warn", o.Info = "info", o.Debug = "debug", o))(s || {});
2
+ function t(o) {
3
+ return `\x1B[${o}`;
4
4
  }
5
- const s = {
6
- black: e("30m"),
7
- red: e("31m"),
8
- green: e("32m"),
9
- yellow: e("33m"),
10
- blue: e("34m"),
11
- magenta: e("35m"),
12
- cyan: e("36m"),
13
- white: e("37m")
5
+ const m = {
6
+ black: t("30m"),
7
+ red: t("31m"),
8
+ green: t("32m"),
9
+ yellow: t("33m"),
10
+ blue: t("34m"),
11
+ magenta: t("35m"),
12
+ cyan: t("36m"),
13
+ white: t("37m")
14
14
  }, n = {
15
- reset: e("0m"),
16
- bold: e("1m"),
17
- dim: e("2m")
15
+ reset: t("0m"),
16
+ bold: t("1m"),
17
+ dim: t("2m")
18
18
  };
19
19
  class u {
20
- constructor(o = {}) {
21
- this.console = o.console ?? console;
20
+ constructor(e = {}) {
21
+ this.console = e.console ?? console;
22
22
  }
23
- processLog(o) {
24
- const l = [
23
+ processLog(e) {
24
+ const i = this.getTimestamp(new Date()), c = [
25
25
  {
26
26
  include: !0,
27
27
  command: "%s",
28
- content: i[o.level]
28
+ content: `${n.reset}${n.dim}${i}${n.reset}`
29
29
  },
30
30
  {
31
31
  include: !0,
32
32
  command: "%s",
33
- content: o.message
33
+ content: d[e.level]
34
34
  },
35
35
  {
36
- include: o.origin.length > 0,
36
+ include: !0,
37
37
  command: "%s",
38
- content: `${n.dim}${o.origin.join(":")}${n.reset}`
38
+ content: e.message
39
39
  },
40
40
  {
41
- include: Object.keys(o.context).length > 0,
41
+ include: e.origin.length > 0,
42
+ command: "%s",
43
+ content: `${n.dim}${e.origin.join(":")}${n.reset}`
44
+ },
45
+ {
46
+ include: Object.keys(e.context).length > 0,
42
47
  command: "%O",
43
- content: o.context
48
+ content: e.context
44
49
  }
45
- ].filter((c) => c.include), m = l.map((c) => c.command).join(" "), a = l.map((c) => c.content), d = o.level === t.Error ? "error" : "log";
46
- this.console[d](m, ...a);
50
+ ].filter((r) => r.include), a = c.map((r) => r.command).join(" "), l = c.map((r) => r.content);
51
+ this.console.error(a, ...l);
52
+ }
53
+ // ISO-8601 timestamp with milliseconds.
54
+ getTimestamp(e) {
55
+ const i = e.getHours().toString().padStart(2, "0"), c = e.getMinutes().toString().padStart(2, "0"), a = e.getSeconds().toString().padStart(2, "0"), l = e.getMilliseconds().toString().padStart(3, "0");
56
+ return `[${i}:${c}:${a}.${l}]`;
47
57
  }
48
58
  }
49
- const i = {
50
- [t.Debug]: `${n.bold}${s.cyan}debug${n.reset}`,
51
- [t.Info]: `${n.bold}${s.green}info${n.reset} `,
52
- [t.Warn]: `${n.bold}${s.yellow}warn${n.reset} `,
53
- [t.Error]: `${n.bold}${s.red}error${n.reset}`
59
+ const d = {
60
+ [s.Debug]: `${m.blue}DEBUG${n.reset}`,
61
+ [s.Info]: `${m.green}INFO${n.reset} `,
62
+ [s.Warn]: `${m.yellow}WARN${n.reset} `,
63
+ [s.Error]: `${m.red}ERROR${n.reset}`
54
64
  };
55
65
  export {
56
66
  u as AnsiTerminalBackend,
57
67
  u as default
58
68
  };
59
- //# sourceMappingURL=holz-ansi-terminal-backend.js.map
@@ -1,2 +1 @@
1
- (function(c,n){typeof exports=="object"&&typeof module<"u"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(c=typeof globalThis<"u"?globalThis:c||self,n(c["holz-ansi-terminal-backend"]={}))})(this,function(c){"use strict";var n=(r=>(r.Error="error",r.Warn="warn",r.Info="info",r.Debug="debug",r))(n||{});function e(r){return`\x1B[${r}`}const s={black:e("30m"),red:e("31m"),green:e("32m"),yellow:e("33m"),blue:e("34m"),magenta:e("35m"),cyan:e("36m"),white:e("37m")},o={reset:e("0m"),bold:e("1m"),dim:e("2m")};class l{constructor(t={}){this.console=t.console??console}processLog(t){const d=[{include:!0,command:"%s",content:m[t.level]},{include:!0,command:"%s",content:t.message},{include:t.origin.length>0,command:"%s",content:`${o.dim}${t.origin.join(":")}${o.reset}`},{include:Object.keys(t.context).length>0,command:"%O",content:t.context}].filter(i=>i.include),a=d.map(i=>i.command).join(" "),u=d.map(i=>i.content),f=t.level===n.Error?"error":"log";this.console[f](a,...u)}}const m={[n.Debug]:`${o.bold}${s.cyan}debug${o.reset}`,[n.Info]:`${o.bold}${s.green}info${o.reset} `,[n.Warn]:`${o.bold}${s.yellow}warn${o.reset} `,[n.Error]:`${o.bold}${s.red}error${o.reset}`};c.AnsiTerminalBackend=l,c.default=l,Object.defineProperties(c,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
2
- //# sourceMappingURL=holz-ansi-terminal-backend.umd.cjs.map
1
+ (function(r,t){typeof exports=="object"&&typeof module<"u"?t(exports):typeof define=="function"&&define.amd?define(["exports"],t):(r=typeof globalThis<"u"?globalThis:r||self,t(r["holz-ansi-terminal-backend"]={}))})(this,function(r){"use strict";var t=(s=>(s.Error="error",s.Warn="warn",s.Info="info",s.Debug="debug",s))(t||{});function n(s){return`\x1B[${s}`}const c={black:n("30m"),red:n("31m"),green:n("32m"),yellow:n("33m"),blue:n("34m"),magenta:n("35m"),cyan:n("36m"),white:n("37m")},o={reset:n("0m"),bold:n("1m"),dim:n("2m")};class u{constructor(e={}){this.console=e.console??console}processLog(e){const d=this.getTimestamp(new Date),m=[{include:!0,command:"%s",content:`${o.reset}${o.dim}${d}${o.reset}`},{include:!0,command:"%s",content:g[e.level]},{include:!0,command:"%s",content:e.message},{include:e.origin.length>0,command:"%s",content:`${o.dim}${e.origin.join(":")}${o.reset}`},{include:Object.keys(e.context).length>0,command:"%O",content:e.context}].filter(i=>i.include),a=m.map(i=>i.command).join(" "),l=m.map(i=>i.content);this.console.error(a,...l)}getTimestamp(e){const d=e.getHours().toString().padStart(2,"0"),m=e.getMinutes().toString().padStart(2,"0"),a=e.getSeconds().toString().padStart(2,"0"),l=e.getMilliseconds().toString().padStart(3,"0");return`[${d}:${m}:${a}.${l}]`}}const g={[t.Debug]:`${c.blue}DEBUG${o.reset}`,[t.Info]:`${c.green}INFO${o.reset} `,[t.Warn]:`${c.yellow}WARN${o.reset} `,[t.Error]:`${c.red}ERROR${o.reset}`};r.AnsiTerminalBackend=u,r.default=u,Object.defineProperties(r,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holz/ansi-terminal-backend",
3
- "version": "0.0.0",
3
+ "version": "0.1.0",
4
4
  "description": "An ANSI terminal backend for Holz",
5
5
  "type": "module",
6
6
  "main": "./dist/holz-ansi-terminal-backend.umd.cjs",
@@ -33,14 +33,15 @@
33
33
  "terminal"
34
34
  ],
35
35
  "scripts": {
36
- "prepare": "vite build --sourcemap",
36
+ "prepare": "vite build",
37
37
  "test:unit": "vitest --color --passWithNoTests",
38
- "test:coverage": "run test:unit --coverage"
38
+ "test:types": "tsc"
39
39
  },
40
40
  "devDependencies": {
41
- "@holz/core": "0.0.0",
41
+ "@holz/core": "0.1.0",
42
42
  "@types/node": "^18.14.0",
43
43
  "@vitest/coverage-c8": "0.28.5",
44
+ "typescript": "4.9.5",
44
45
  "vite": "^4.0.0",
45
46
  "vitest": "^0.28.5"
46
47
  }
@@ -3,6 +3,8 @@ import { createLogger } from '@holz/core';
3
3
  import type { MinimalConsole } from '../ansi-terminal-backend';
4
4
  import AnsiTerminalBackend from '../ansi-terminal-backend';
5
5
 
6
+ const CURRENT_TIME = new Date('2020-06-15T03:05:07.010Z');
7
+
6
8
  class MockConsole implements MinimalConsole {
7
9
  log(...strings: Array<unknown>) {
8
10
  this.stdout(format(...strings));
@@ -16,7 +18,17 @@ class MockConsole implements MinimalConsole {
16
18
  stderr = vi.fn();
17
19
  }
18
20
 
19
- describe('Terminal backend', () => {
21
+ describe('ANSI terminal backend', () => {
22
+ beforeEach(() => {
23
+ vi.useFakeTimers({
24
+ now: CURRENT_TIME,
25
+ });
26
+ });
27
+
28
+ afterEach(() => {
29
+ vi.useRealTimers();
30
+ });
31
+
20
32
  it('prints the message to the terminal', () => {
21
33
  const terminal = new MockConsole();
22
34
  const backend = new AnsiTerminalBackend({ console: terminal });
@@ -24,7 +36,7 @@ describe('Terminal backend', () => {
24
36
  const logger = createLogger(backend);
25
37
  logger.info('hello world');
26
38
 
27
- expect(terminal.stdout).toHaveBeenCalledWith(
39
+ expect(terminal.stderr).toHaveBeenCalledWith(
28
40
  expect.stringContaining('hello world')
29
41
  );
30
42
  });
@@ -39,20 +51,20 @@ describe('Terminal backend', () => {
39
51
  logger.warn('hmmmm');
40
52
  logger.error('oh no');
41
53
 
42
- expect(terminal.stdout).toHaveBeenCalledWith(
43
- expect.stringContaining('debug')
54
+ expect(terminal.stderr).toHaveBeenCalledWith(
55
+ expect.stringContaining('DEBUG')
44
56
  );
45
57
 
46
- expect(terminal.stdout).toHaveBeenCalledWith(
47
- expect.stringContaining('info')
58
+ expect(terminal.stderr).toHaveBeenCalledWith(
59
+ expect.stringContaining('INFO')
48
60
  );
49
61
 
50
- expect(terminal.stdout).toHaveBeenCalledWith(
51
- expect.stringContaining('warn')
62
+ expect(terminal.stderr).toHaveBeenCalledWith(
63
+ expect.stringContaining('WARN')
52
64
  );
53
65
 
54
66
  expect(terminal.stderr).toHaveBeenCalledWith(
55
- expect.stringContaining('error')
67
+ expect.stringContaining('ERROR')
56
68
  );
57
69
  });
58
70
 
@@ -65,7 +77,7 @@ describe('Terminal backend', () => {
65
77
 
66
78
  logger.debug('initialized');
67
79
 
68
- expect(terminal.stdout).toHaveBeenCalledWith(
80
+ expect(terminal.stderr).toHaveBeenCalledWith(
69
81
  expect.stringContaining('my-lib:MyClass')
70
82
  );
71
83
  });
@@ -78,11 +90,11 @@ describe('Terminal backend', () => {
78
90
  logger.info('creating session', { sessionId: 3109 });
79
91
 
80
92
  // Hard to test without replicating the implementation.
81
- expect(terminal.stdout).toHaveBeenCalledWith(
93
+ expect(terminal.stderr).toHaveBeenCalledWith(
82
94
  expect.stringContaining('sessionId')
83
95
  );
84
96
 
85
- expect(terminal.stdout).toHaveBeenCalledWith(
97
+ expect(terminal.stderr).toHaveBeenCalledWith(
86
98
  expect.stringContaining('3109')
87
99
  );
88
100
  });
@@ -95,11 +107,11 @@ describe('Terminal backend', () => {
95
107
  logger.warn('activating death ray', {});
96
108
 
97
109
  // Hard to test without replicating the implementation.
98
- expect(terminal.stdout).not.toHaveBeenCalledWith(
110
+ expect(terminal.stderr).not.toHaveBeenCalledWith(
99
111
  expect.stringContaining('{')
100
112
  );
101
113
 
102
- expect(terminal.stdout).not.toHaveBeenCalledWith(
114
+ expect(terminal.stderr).not.toHaveBeenCalledWith(
103
115
  expect.stringContaining('}')
104
116
  );
105
117
  });
@@ -19,7 +19,13 @@ export default class AnsiTerminalBackend implements LogProcessor {
19
19
  }
20
20
 
21
21
  processLog(log: Log) {
22
+ const timestamp = this.getTimestamp(new Date());
22
23
  const segments = [
24
+ {
25
+ include: true,
26
+ command: '%s',
27
+ content: `${code.reset}${code.dim}${timestamp}${code.reset}`,
28
+ },
23
29
  {
24
30
  include: true,
25
31
  command: '%s',
@@ -42,22 +48,30 @@ export default class AnsiTerminalBackend implements LogProcessor {
42
48
  },
43
49
  ].filter((segment) => segment.include);
44
50
 
45
- const command = segments.map((segment) => segment.command).join(' ');
51
+ const format = segments.map((segment) => segment.command).join(' ');
46
52
  const values = segments.map((segment) => segment.content);
47
53
 
48
- // Errors should always use stderr.
49
- const channel: keyof MinimalConsole =
50
- log.level === LogLevel.Error ? 'error' : 'log';
54
+ // CLIs typically print interactive messages to stdout and logs to stderr.
55
+ this.console.error(format, ...values);
56
+ }
57
+
58
+ // ISO-8601 timestamp with milliseconds.
59
+ private getTimestamp(date: Date) {
60
+ const hours = date.getHours().toString().padStart(2, '0');
61
+ const minutes = date.getMinutes().toString().padStart(2, '0');
62
+ const seconds = date.getSeconds().toString().padStart(2, '0');
63
+ const milliseconds = date.getMilliseconds().toString().padStart(3, '0');
51
64
 
52
- this.console[channel](command, ...values);
65
+ return `[${hours}:${minutes}:${seconds}.${milliseconds}]`;
53
66
  }
54
67
  }
55
68
 
69
+ // Trailing whitespace is important for alignment.
56
70
  const logLevelLabel: Record<LogLevel, string> = {
57
- [LogLevel.Debug]: `${code.bold}${color.cyan}debug${code.reset}`,
58
- [LogLevel.Info]: `${code.bold}${color.green}info${code.reset} `,
59
- [LogLevel.Warn]: `${code.bold}${color.yellow}warn${code.reset} `,
60
- [LogLevel.Error]: `${code.bold}${color.red}error${code.reset}`,
71
+ [LogLevel.Debug]: `${color.blue}DEBUG${code.reset}`,
72
+ [LogLevel.Info]: `${color.green}INFO${code.reset} `,
73
+ [LogLevel.Warn]: `${color.yellow}WARN${code.reset} `,
74
+ [LogLevel.Error]: `${color.red}ERROR${code.reset}`,
61
75
  };
62
76
 
63
77
  interface Options {
@@ -66,11 +80,6 @@ interface Options {
66
80
 
67
81
  /**
68
82
  * A subset of the Console interface. Must support printf-style interpolation.
83
+ * @see https://console.spec.whatwg.org/#formatting-specifiers
69
84
  */
70
- export interface MinimalConsole {
71
- /** Log to stdout. */
72
- log: Console['log'];
73
-
74
- /** Log to stderr. */
75
- error: Console['error'];
76
- }
85
+ export type MinimalConsole = Pick<Console, 'log' | 'error'>;
package/CHANGELOG.md DELETED
@@ -1,7 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
-
7
- ## Unreleased
@@ -1 +0,0 @@
1
- {"version":3,"file":"holz-ansi-terminal-backend.js","sources":["../../holz-core/dist/holz-core.js","../src/ansi-codes.ts","../src/ansi-terminal-backend.ts"],"sourcesContent":["var t = /* @__PURE__ */ ((s) => (s.Error = \"error\", s.Warn = \"warn\", s.Info = \"info\", s.Debug = \"debug\", s))(t || {});\nclass e {\n constructor(r, o) {\n this.processor = r, this.origin = o;\n }\n static create(r) {\n return new e(r, []);\n }\n /** Extend the logger to attach a class or module name to logs. */\n namespace(r) {\n return new e(this.processor, this.origin.concat(r));\n }\n /** Log a frequent and verbose progress update. */\n debug(r, o) {\n this.forwardLog(t.Debug, r, o);\n }\n /** Log a high-level progress update. */\n info(r, o) {\n this.forwardLog(t.Info, r, o);\n }\n /** Log something concerning. */\n warn(r, o) {\n this.forwardLog(t.Warn, r, o);\n }\n /** Log a critical failure. */\n error(r, o) {\n this.forwardLog(t.Error, r, o);\n }\n forwardLog(r, o, c = {}) {\n this.processor.processLog({\n message: o,\n level: r,\n origin: this.origin,\n context: c\n });\n }\n}\nconst a = e.create;\nclass i {\n constructor(r) {\n this.processors = r;\n }\n processLog(r) {\n this.processors.forEach((o) => {\n o.processLog(r);\n });\n }\n}\nfunction h(s) {\n return new i(s);\n}\nclass n {\n constructor(r, o) {\n this.predicate = r, this.processor = o;\n }\n processLog(r) {\n this.predicate(r) && this.processor.processLog(r);\n }\n}\nfunction g(s, r) {\n return new n(s, r);\n}\nexport {\n t as LogLevel,\n h as combine,\n a as createLogger,\n g as filter\n};\n//# sourceMappingURL=holz-core.js.map\n","function ansiCode(code: string) {\n return `\\x1b[${code}`;\n}\n\n/**\n * Unix only. This will break for win32 terminals and may spew garbage on\n * terminals without 4-bit color support.\n *\n * TODO: Strip colors on non-interactive TTYs.\n */\n\nexport const color = {\n black: ansiCode('30m'),\n red: ansiCode('31m'),\n green: ansiCode('32m'),\n yellow: ansiCode('33m'),\n blue: ansiCode('34m'),\n magenta: ansiCode('35m'),\n cyan: ansiCode('36m'),\n white: ansiCode('37m'),\n};\n\nexport const code = {\n reset: ansiCode('0m'),\n bold: ansiCode('1m'),\n dim: ansiCode('2m'),\n};\n","import type { Log, LogProcessor } from '@holz/core';\nimport { LogLevel } from '@holz/core';\nimport { color, code } from './ansi-codes';\n\n/**\n * A backend that prints logs to a 3-bit ansi terminal. This should work on\n * most Unix systems and Windows >= 10.\n *\n * NOTE: This is not smart enough to detect if the output is a TTY or if it\n * supports colors, nor is this the appropriate place to check. Without color\n * ques, the printed text is much less understandable. It is better to check\n * when constructing the logger instead.\n */\nexport default class AnsiTerminalBackend implements LogProcessor {\n private console: MinimalConsole;\n\n constructor(options: Options = {}) {\n this.console = options.console ?? console;\n }\n\n processLog(log: Log) {\n const segments = [\n {\n include: true,\n command: '%s',\n content: logLevelLabel[log.level],\n },\n {\n include: true,\n command: '%s',\n content: log.message,\n },\n {\n include: log.origin.length > 0,\n command: '%s',\n content: `${code.dim}${log.origin.join(':')}${code.reset}`,\n },\n {\n include: Object.keys(log.context).length > 0,\n command: '%O',\n content: log.context,\n },\n ].filter((segment) => segment.include);\n\n const command = segments.map((segment) => segment.command).join(' ');\n const values = segments.map((segment) => segment.content);\n\n // Errors should always use stderr.\n const channel: keyof MinimalConsole =\n log.level === LogLevel.Error ? 'error' : 'log';\n\n this.console[channel](command, ...values);\n }\n}\n\nconst logLevelLabel: Record<LogLevel, string> = {\n [LogLevel.Debug]: `${code.bold}${color.cyan}debug${code.reset}`,\n [LogLevel.Info]: `${code.bold}${color.green}info${code.reset} `,\n [LogLevel.Warn]: `${code.bold}${color.yellow}warn${code.reset} `,\n [LogLevel.Error]: `${code.bold}${color.red}error${code.reset}`,\n};\n\ninterface Options {\n console?: MinimalConsole;\n}\n\n/**\n * A subset of the Console interface. Must support printf-style interpolation.\n */\nexport interface MinimalConsole {\n /** Log to stdout. */\n log: Console['log'];\n\n /** Log to stderr. */\n error: Console['error'];\n}\n"],"names":["s","ansiCode","code","color","AnsiTerminalBackend","options","log","segments","logLevelLabel","segment","command","values","channel","LogLevel"],"mappings":"AAAA,IAAI,IAAqB,kBAACA,OAAOA,EAAE,QAAQ,SAASA,EAAE,OAAO,QAAQA,EAAE,OAAO,QAAQA,EAAE,QAAQ,SAASA,IAAI,KAAK,EAAE;ACApH,SAASC,EAASC,GAAc;AAC9B,SAAO,QAAQA;AACjB;AASO,MAAMC,IAAQ;AAAA,EACnB,OAAOF,EAAS,KAAK;AAAA,EACrB,KAAKA,EAAS,KAAK;AAAA,EACnB,OAAOA,EAAS,KAAK;AAAA,EACrB,QAAQA,EAAS,KAAK;AAAA,EACtB,MAAMA,EAAS,KAAK;AAAA,EACpB,SAASA,EAAS,KAAK;AAAA,EACvB,MAAMA,EAAS,KAAK;AAAA,EACpB,OAAOA,EAAS,KAAK;AACvB,GAEaC,IAAO;AAAA,EAClB,OAAOD,EAAS,IAAI;AAAA,EACpB,MAAMA,EAAS,IAAI;AAAA,EACnB,KAAKA,EAAS,IAAI;AACpB;ACbA,MAAqBG,EAA4C;AAAA,EAG/D,YAAYC,IAAmB,IAAI;AAC5B,SAAA,UAAUA,EAAQ,WAAW;AAAA,EACpC;AAAA,EAEA,WAAWC,GAAU;AACnB,UAAMC,IAAW;AAAA,MACf;AAAA,QACE,SAAS;AAAA,QACT,SAAS;AAAA,QACT,SAASC,EAAcF,EAAI,KAAK;AAAA,MAClC;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,SAAS;AAAA,QACT,SAASA,EAAI;AAAA,MACf;AAAA,MACA;AAAA,QACE,SAASA,EAAI,OAAO,SAAS;AAAA,QAC7B,SAAS;AAAA,QACT,SAAS,GAAGJ,EAAK,MAAMI,EAAI,OAAO,KAAK,GAAG,IAAIJ,EAAK;AAAA,MACrD;AAAA,MACA;AAAA,QACE,SAAS,OAAO,KAAKI,EAAI,OAAO,EAAE,SAAS;AAAA,QAC3C,SAAS;AAAA,QACT,SAASA,EAAI;AAAA,MACf;AAAA,IACA,EAAA,OAAO,CAACG,MAAYA,EAAQ,OAAO,GAE/BC,IAAUH,EAAS,IAAI,CAACE,MAAYA,EAAQ,OAAO,EAAE,KAAK,GAAG,GAC7DE,IAASJ,EAAS,IAAI,CAACE,MAAYA,EAAQ,OAAO,GAGlDG,IACJN,EAAI,UAAUO,EAAS,QAAQ,UAAU;AAE3C,SAAK,QAAQD,CAAO,EAAEF,GAAS,GAAGC,CAAM;AAAA,EAC1C;AACF;AAEA,MAAMH,IAA0C;AAAA,EAC9C,CAACK,EAAS,KAAK,GAAG,GAAGX,EAAK,OAAOC,EAAM,YAAYD,EAAK;AAAA,EACxD,CAACW,EAAS,IAAI,GAAG,GAAGX,EAAK,OAAOC,EAAM,YAAYD,EAAK;AAAA,EACvD,CAACW,EAAS,IAAI,GAAG,GAAGX,EAAK,OAAOC,EAAM,aAAaD,EAAK;AAAA,EACxD,CAACW,EAAS,KAAK,GAAG,GAAGX,EAAK,OAAOC,EAAM,WAAWD,EAAK;AACzD;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"holz-ansi-terminal-backend.umd.cjs","sources":["../../holz-core/dist/holz-core.js","../src/ansi-codes.ts","../src/ansi-terminal-backend.ts"],"sourcesContent":["var t = /* @__PURE__ */ ((s) => (s.Error = \"error\", s.Warn = \"warn\", s.Info = \"info\", s.Debug = \"debug\", s))(t || {});\nclass e {\n constructor(r, o) {\n this.processor = r, this.origin = o;\n }\n static create(r) {\n return new e(r, []);\n }\n /** Extend the logger to attach a class or module name to logs. */\n namespace(r) {\n return new e(this.processor, this.origin.concat(r));\n }\n /** Log a frequent and verbose progress update. */\n debug(r, o) {\n this.forwardLog(t.Debug, r, o);\n }\n /** Log a high-level progress update. */\n info(r, o) {\n this.forwardLog(t.Info, r, o);\n }\n /** Log something concerning. */\n warn(r, o) {\n this.forwardLog(t.Warn, r, o);\n }\n /** Log a critical failure. */\n error(r, o) {\n this.forwardLog(t.Error, r, o);\n }\n forwardLog(r, o, c = {}) {\n this.processor.processLog({\n message: o,\n level: r,\n origin: this.origin,\n context: c\n });\n }\n}\nconst a = e.create;\nclass i {\n constructor(r) {\n this.processors = r;\n }\n processLog(r) {\n this.processors.forEach((o) => {\n o.processLog(r);\n });\n }\n}\nfunction h(s) {\n return new i(s);\n}\nclass n {\n constructor(r, o) {\n this.predicate = r, this.processor = o;\n }\n processLog(r) {\n this.predicate(r) && this.processor.processLog(r);\n }\n}\nfunction g(s, r) {\n return new n(s, r);\n}\nexport {\n t as LogLevel,\n h as combine,\n a as createLogger,\n g as filter\n};\n//# sourceMappingURL=holz-core.js.map\n","function ansiCode(code: string) {\n return `\\x1b[${code}`;\n}\n\n/**\n * Unix only. This will break for win32 terminals and may spew garbage on\n * terminals without 4-bit color support.\n *\n * TODO: Strip colors on non-interactive TTYs.\n */\n\nexport const color = {\n black: ansiCode('30m'),\n red: ansiCode('31m'),\n green: ansiCode('32m'),\n yellow: ansiCode('33m'),\n blue: ansiCode('34m'),\n magenta: ansiCode('35m'),\n cyan: ansiCode('36m'),\n white: ansiCode('37m'),\n};\n\nexport const code = {\n reset: ansiCode('0m'),\n bold: ansiCode('1m'),\n dim: ansiCode('2m'),\n};\n","import type { Log, LogProcessor } from '@holz/core';\nimport { LogLevel } from '@holz/core';\nimport { color, code } from './ansi-codes';\n\n/**\n * A backend that prints logs to a 3-bit ansi terminal. This should work on\n * most Unix systems and Windows >= 10.\n *\n * NOTE: This is not smart enough to detect if the output is a TTY or if it\n * supports colors, nor is this the appropriate place to check. Without color\n * ques, the printed text is much less understandable. It is better to check\n * when constructing the logger instead.\n */\nexport default class AnsiTerminalBackend implements LogProcessor {\n private console: MinimalConsole;\n\n constructor(options: Options = {}) {\n this.console = options.console ?? console;\n }\n\n processLog(log: Log) {\n const segments = [\n {\n include: true,\n command: '%s',\n content: logLevelLabel[log.level],\n },\n {\n include: true,\n command: '%s',\n content: log.message,\n },\n {\n include: log.origin.length > 0,\n command: '%s',\n content: `${code.dim}${log.origin.join(':')}${code.reset}`,\n },\n {\n include: Object.keys(log.context).length > 0,\n command: '%O',\n content: log.context,\n },\n ].filter((segment) => segment.include);\n\n const command = segments.map((segment) => segment.command).join(' ');\n const values = segments.map((segment) => segment.content);\n\n // Errors should always use stderr.\n const channel: keyof MinimalConsole =\n log.level === LogLevel.Error ? 'error' : 'log';\n\n this.console[channel](command, ...values);\n }\n}\n\nconst logLevelLabel: Record<LogLevel, string> = {\n [LogLevel.Debug]: `${code.bold}${color.cyan}debug${code.reset}`,\n [LogLevel.Info]: `${code.bold}${color.green}info${code.reset} `,\n [LogLevel.Warn]: `${code.bold}${color.yellow}warn${code.reset} `,\n [LogLevel.Error]: `${code.bold}${color.red}error${code.reset}`,\n};\n\ninterface Options {\n console?: MinimalConsole;\n}\n\n/**\n * A subset of the Console interface. Must support printf-style interpolation.\n */\nexport interface MinimalConsole {\n /** Log to stdout. */\n log: Console['log'];\n\n /** Log to stderr. */\n error: Console['error'];\n}\n"],"names":["t","s","ansiCode","code","color","AnsiTerminalBackend","options","log","segments","logLevelLabel","segment","command","values","channel","LogLevel"],"mappings":"qPAAA,IAAIA,GAAsBC,IAAOA,EAAE,MAAQ,QAASA,EAAE,KAAO,OAAQA,EAAE,KAAO,OAAQA,EAAE,MAAQ,QAASA,IAAID,GAAK,EAAE,ECApH,SAASE,EAASC,EAAc,CAC9B,MAAO,QAAQA,GACjB,CASO,MAAMC,EAAQ,CACnB,MAAOF,EAAS,KAAK,EACrB,IAAKA,EAAS,KAAK,EACnB,MAAOA,EAAS,KAAK,EACrB,OAAQA,EAAS,KAAK,EACtB,KAAMA,EAAS,KAAK,EACpB,QAASA,EAAS,KAAK,EACvB,KAAMA,EAAS,KAAK,EACpB,MAAOA,EAAS,KAAK,CACvB,EAEaC,EAAO,CAClB,MAAOD,EAAS,IAAI,EACpB,KAAMA,EAAS,IAAI,EACnB,IAAKA,EAAS,IAAI,CACpB,ECbA,MAAqBG,CAA4C,CAG/D,YAAYC,EAAmB,GAAI,CAC5B,KAAA,QAAUA,EAAQ,SAAW,OACpC,CAEA,WAAWC,EAAU,CACnB,MAAMC,EAAW,CACf,CACE,QAAS,GACT,QAAS,KACT,QAASC,EAAcF,EAAI,KAAK,CAClC,EACA,CACE,QAAS,GACT,QAAS,KACT,QAASA,EAAI,OACf,EACA,CACE,QAASA,EAAI,OAAO,OAAS,EAC7B,QAAS,KACT,QAAS,GAAGJ,EAAK,MAAMI,EAAI,OAAO,KAAK,GAAG,IAAIJ,EAAK,OACrD,EACA,CACE,QAAS,OAAO,KAAKI,EAAI,OAAO,EAAE,OAAS,EAC3C,QAAS,KACT,QAASA,EAAI,OACf,CACA,EAAA,OAAQG,GAAYA,EAAQ,OAAO,EAE/BC,EAAUH,EAAS,IAAKE,GAAYA,EAAQ,OAAO,EAAE,KAAK,GAAG,EAC7DE,EAASJ,EAAS,IAAKE,GAAYA,EAAQ,OAAO,EAGlDG,EACJN,EAAI,QAAUO,EAAS,MAAQ,QAAU,MAE3C,KAAK,QAAQD,CAAO,EAAEF,EAAS,GAAGC,CAAM,CAC1C,CACF,CAEA,MAAMH,EAA0C,CAC9C,CAACK,EAAS,KAAK,EAAG,GAAGX,EAAK,OAAOC,EAAM,YAAYD,EAAK,QACxD,CAACW,EAAS,IAAI,EAAG,GAAGX,EAAK,OAAOC,EAAM,YAAYD,EAAK,SACvD,CAACW,EAAS,IAAI,EAAG,GAAGX,EAAK,OAAOC,EAAM,aAAaD,EAAK,SACxD,CAACW,EAAS,KAAK,EAAG,GAAGX,EAAK,OAAOC,EAAM,WAAWD,EAAK,OACzD"}