@idlebox/logger 0.0.4 → 0.0.6

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,11 +1,13 @@
1
1
  import { relative } from 'node:path';
2
2
  import { formatWithOptions, inspect } from 'node:util';
3
+ import { Cdim, Cdimita, CFgreen, CFred, Cita, Crst, NCF, NCita } from './ansi.js';
4
+ import type { IDebugCommand } from './types.js';
3
5
 
4
6
  const STRING_MAX_LENGTH = 128;
5
7
 
6
8
  function color_error(message: string, color: boolean) {
7
9
  if (color) {
8
- return `\x1B[38;5;9m<inspect**${message}**>\x1B[39m`;
10
+ return `${CFred}<inspect**${message}**>${NCF}`;
9
11
  } else {
10
12
  return `<inspect**${message}**>`;
11
13
  }
@@ -33,7 +35,7 @@ function isSyncIterable(obj: unknown): obj is Iterable<unknown> {
33
35
  return typeof obj === 'object' && obj !== null && Symbol.iterator in obj;
34
36
  }
35
37
 
36
- const debug_commands = {
38
+ export const debug_commands: Record<string, IDebugCommand> = {
37
39
  inspect(object: unknown, color: boolean) {
38
40
  return inspect(object, options(color));
39
41
  },
@@ -41,24 +43,30 @@ const debug_commands = {
41
43
  if (typeof s !== 'string') {
42
44
  return color_error(`can not stripe ${typeof s}`, color);
43
45
  }
44
- if (s.length > 100) {
46
+ let str = s;
47
+ str = str.replace(/\n/g, '\\n');
48
+ str = str.replace(/\r/g, '\\r');
49
+ str = str.replace(/\t/g, '\\t');
50
+ str = str.replace(/\x1B/g, '\\e');
51
+ if (str.length > STRING_MAX_LENGTH) {
52
+ const chars = `(${str.length.toFixed(0)} chars)`;
45
53
  if (color) {
46
- return `\x1B[38;5;10m"${s.slice(0, STRING_MAX_LENGTH - 3)}..."\x1B[39m`;
54
+ return `"${CFgreen}${str.slice(0, STRING_MAX_LENGTH - chars.length - 3)}...${NCF} ${chars}"`;
47
55
  } else {
48
- return `"${s.slice(0, STRING_MAX_LENGTH - 3)}..."`;
56
+ return `"${CFgreen}${str}${NCF}"`;
49
57
  }
50
58
  } else {
51
- return s;
59
+ return str;
52
60
  }
53
61
  },
54
62
  list(items: unknown, color: boolean) {
55
63
  if (!isSyncIterable(items)) {
56
64
  return color_error(`list<> need iterable value, not ${typeof items}(${items?.constructor?.name})`, color);
57
65
  }
58
- const postfix = color ? '\x1B[0m' : '';
66
+ const postfix = color ? Crst : '';
59
67
  let index = 0;
60
68
  const lines: string[] = [];
61
- const prefix = color ? '\x1B[2m' : '';
69
+ const prefix = color ? Cdim : '';
62
70
  for (const item of items) {
63
71
  if (Array.isArray(item)) {
64
72
  if (item.length === 2) {
@@ -78,19 +86,19 @@ const debug_commands = {
78
86
  }
79
87
 
80
88
  if (lines.length === 0) {
81
- const prefix = color ? '\x1B[3;2m' : '';
82
- return ':\n' + prefix + ' - <list is empty>' + postfix;
89
+ const prefix = color ? Cdimita : '';
90
+ return `:\n${prefix} - <list is empty>${postfix}`;
83
91
  }
84
- return ':\n' + lines.join('\n');
92
+ return `:\n${lines.join('\n')}`;
85
93
  },
86
94
  commandline(cmds: unknown, color: boolean) {
87
95
  if (Array.isArray(cmds)) {
88
- const prefix = color ? '\x1B[2m' : '';
89
- const postfix = color ? '\x1B[0m' : '';
96
+ const prefix = color ? Cdim : '';
97
+ const postfix = color ? Crst : '';
90
98
  return prefix + cmds.map((s) => JSON.stringify(s)).join(' ') + postfix;
91
99
  } else if (typeof cmds === 'string') {
92
- const prefix = color ? '\x1B[2;3m' : '';
93
- const postfix = color ? '\x1B[0m' : '';
100
+ const prefix = color ? Cdimita : '';
101
+ const postfix = color ? Crst : '';
94
102
  return prefix + cmds + postfix;
95
103
  } else {
96
104
  return color_error(`commandline<> need string or array, not ${typeof cmds}`, color);
@@ -105,9 +113,9 @@ const debug_commands = {
105
113
  }
106
114
  }
107
115
  if (color) {
108
- return `\x1B[3m${s}\x1B[23m`;
116
+ return `${Cita}${s}${NCita}`;
109
117
  } else {
110
- return s;
118
+ return s as string;
111
119
  }
112
120
  },
113
121
  relative(s: unknown, color: boolean) {
@@ -119,11 +127,7 @@ const debug_commands = {
119
127
  };
120
128
  type DebugCommands = Record<string, (arg: unknown, color: boolean) => string>;
121
129
 
122
- export function call_debug_command(
123
- command: keyof typeof debug_commands | string,
124
- arg: unknown,
125
- color: boolean,
126
- ): string {
130
+ export function call_debug_command(command: keyof typeof debug_commands | string, arg: unknown, color: boolean): string {
127
131
  const fn = (debug_commands as DebugCommands)[command];
128
132
  if (!fn) {
129
133
  return color_error(`unknown command ${command}`, color);
@@ -1,7 +1,9 @@
1
+ import { prettyFormatError } from '@idlebox/common';
1
2
  import debug from 'debug';
2
3
  import process from 'node:process';
4
+ import { debug_commands } from './debug.commands.js';
3
5
  import { terminal } from './logger.global.js';
4
- import { EnableLogLevel } from './types.js';
6
+ import { EnableLogLevel, type IDebugCommand } from './types.js';
5
7
 
6
8
  /**
7
9
  * 判断 字符串是否为“真值”
@@ -69,7 +71,7 @@ export function detectColorEnable(stream: IWritableStream = process.stderr): boo
69
71
  }
70
72
 
71
73
  export function escapeRegExp(str: string) {
72
- return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
74
+ return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
73
75
  }
74
76
 
75
77
  /**
@@ -81,9 +83,9 @@ export function compile_match_regex(tag: string, invert = false): RegExp {
81
83
  const parts = tag.split(':');
82
84
  parts.pop();
83
85
 
84
- let regs = ['\\*'];
86
+ const regs = ['\\*'];
85
87
 
86
- let comb = [];
88
+ const comb = [];
87
89
  for (const part of parts) {
88
90
  comb.push(part);
89
91
  regs.push(`${escapeRegExp(comb.join(':'))}:\\*`);
@@ -183,3 +185,32 @@ export let defaultLogLevel = (() => {
183
185
  export function set_default_log_level(level: EnableLogLevel) {
184
186
  defaultLogLevel = level;
185
187
  }
188
+
189
+ type ErrorAction = 'stack' | 'message' | 'stack-pretty' | 'inspect' | IDebugCommand;
190
+ const actions = {
191
+ stack(e: Error, _color: boolean) {
192
+ return e.stack || e.message || e?.toString() || '*unknown error*';
193
+ },
194
+ message(e: Error, _color: boolean) {
195
+ return e.message || e?.toString() || '*unknown error*';
196
+ },
197
+ ['stack-pretty']: (e: Error, _color: boolean) => {
198
+ return prettyFormatError(e);
199
+ },
200
+ };
201
+ export let current_error_action = actions.stack;
202
+ export function set_error_action(action: ErrorAction) {
203
+ switch (action) {
204
+ case 'stack':
205
+ case 'message':
206
+ case 'stack-pretty':
207
+ current_error_action = actions[action];
208
+ break;
209
+ case 'inspect':
210
+ current_error_action = debug_commands.inspect;
211
+ break;
212
+ default:
213
+ current_error_action = action;
214
+ break;
215
+ }
216
+ }
@@ -11,11 +11,7 @@ import { EnableLogLevel, type IMyLogger } from './types.js';
11
11
  * @param pipeTo 默认是 process.stderr
12
12
  * @returns
13
13
  */
14
- export function createLogger(
15
- tag: string,
16
- color_enabled: boolean | undefined = undefined,
17
- pipeTo: undefined | NodeJS.WritableStream = process.stderr,
18
- ): IMyLogger {
14
+ export function createLogger(tag: string, color_enabled: boolean | undefined = undefined, pipeTo: undefined | NodeJS.WritableStream = process.stderr): IMyLogger {
19
15
  const stream = new PassThrough();
20
16
  if (pipeTo) {
21
17
  Object.assign(stream, { isTTY: (pipeTo as any).isTTY });
@@ -37,3 +37,5 @@ export type IMyLogger = {
37
37
  readonly tag: string;
38
38
  readonly colorEnabled: boolean;
39
39
  };
40
+
41
+ export type IDebugCommand = (object: unknown, color: boolean) => string;
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ export {
8
8
  match_disabled,
9
9
  match_enabled,
10
10
  set_default_log_level,
11
+ set_error_action,
11
12
  } from './common/helpers.js';
12
13
  export { createLogger } from './common/logger.create.js';
13
14
  export {
@@ -19,5 +20,8 @@ export {
19
20
  type IMyDebug,
20
21
  type IMyDebugWithControl,
21
22
  type IMyLogger,
23
+ type IDebugCommand,
22
24
  } from './common/types.js';
23
25
  export { createLogFile } from './printers/file.js';
26
+
27
+ export { CSI } from './common/ansi.js';