nightingale 16.1.0 → 16.2.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,5 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-use-before-define */
2
2
  import type { Styles } from "nightingale-types";
3
+ import { formatStyles } from "./formatStyles";
3
4
 
4
5
  export interface FormatObjectOptions {
5
6
  padding?: string;
@@ -62,6 +63,57 @@ const sameRawFormattedValue = (value: string): FormattedValue => ({
62
63
  formattedValue: value,
63
64
  });
64
65
 
66
+ const numericSeparator = "_";
67
+
68
+ const formatIntegerValue = (integerAsString: string): string => {
69
+ let result = "";
70
+ let i = integerAsString.length;
71
+ const start = integerAsString.startsWith("-") ? 1 : 0;
72
+ for (; i >= start + 4; i -= 3) {
73
+ result = `${numericSeparator}${integerAsString.slice(i - 3, i)}${result}`;
74
+ }
75
+ return i === integerAsString.length
76
+ ? integerAsString
77
+ : `${integerAsString.slice(0, i)}${result}`;
78
+ };
79
+
80
+ const formatDecimalIntegerValue = (integerAsString: string): string => {
81
+ let result = "";
82
+ let i = 0;
83
+ for (; i < integerAsString.length - 3; i += 3) {
84
+ result += `${integerAsString.slice(i, i + 3)}${numericSeparator}`;
85
+ }
86
+ return i === 0 ? integerAsString : `${result}${integerAsString.slice(i)}`;
87
+ };
88
+
89
+ const formatNumberValue = (value: number): string => {
90
+ if (Number.isNaN(value)) {
91
+ return "NaN";
92
+ }
93
+ if (value === Number.POSITIVE_INFINITY) {
94
+ return "+Infinity";
95
+ }
96
+ if (value === Number.NEGATIVE_INFINITY) {
97
+ return "-Infinity";
98
+ }
99
+ if (value === Number.EPSILON) {
100
+ return "Epsilon";
101
+ }
102
+ if (Object.is(value, -0)) {
103
+ return "-0";
104
+ }
105
+ const integer = Math.trunc(value);
106
+ const integerAsString = integer.toString();
107
+ if (integer === value) {
108
+ if (integerAsString.includes("e")) {
109
+ return integerAsString;
110
+ }
111
+ return formatIntegerValue(integerAsString);
112
+ } else {
113
+ return `${formatIntegerValue(integerAsString)}.${formatDecimalIntegerValue(String(value).slice(integerAsString.length + 1))}`;
114
+ }
115
+ };
116
+
65
117
  function internalFormatValue(
66
118
  value: unknown,
67
119
  styleFn: StyleFn,
@@ -71,30 +123,42 @@ function internalFormatValue(
71
123
  const typeofValue = typeof value;
72
124
 
73
125
  if (!styles) {
74
- if (value == null) {
75
- styles = ["cyan"];
126
+ if (value === null) {
127
+ styles = ["bold"];
76
128
  } else {
77
129
  switch (typeofValue) {
78
- case "undefined":
79
- styles = ["cyan"];
130
+ case "bigint":
131
+ styles = formatStyles.bigint;
80
132
  break;
81
133
  case "boolean":
82
- styles = ["green"];
134
+ styles = formatStyles.boolean;
83
135
  break;
84
- case "number":
85
- styles = ["yellow"];
136
+ case "undefined":
137
+ styles = formatStyles.undefined;
86
138
  break;
87
- case "bigint":
88
- styles = ["red"];
139
+ case "number":
140
+ styles = formatStyles.number;
89
141
  break;
90
142
  case "string":
91
- styles = ["orange"];
143
+ styles = formatStyles.string;
92
144
  break;
93
145
  case "symbol":
94
- styles = ["magenta"];
146
+ styles = formatStyles.symbol;
95
147
  break;
96
148
  case "object":
149
+ if (value instanceof Date) {
150
+ styles = formatStyles.date;
151
+ }
152
+ if (value instanceof RegExp) {
153
+ styles = formatStyles.regexp;
154
+ }
155
+ if (value instanceof Error) {
156
+ styles = formatStyles.error;
157
+ }
158
+ break;
97
159
  case "function":
160
+ styles = formatStyles.function;
161
+ break;
98
162
  default:
99
163
  break;
100
164
  }
@@ -106,6 +170,8 @@ function internalFormatValue(
106
170
  stringValue = "null";
107
171
  } else if (value === undefined) {
108
172
  stringValue = "undefined";
173
+ } else if (typeofValue === "number") {
174
+ stringValue = formatNumberValue(value as number);
109
175
  } else if (typeofValue === "boolean") {
110
176
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
111
177
  stringValue = (value as any).toString() as string;
@@ -156,7 +222,7 @@ function internalFormatValue(
156
222
  });
157
223
  }
158
224
  } else if (typeofValue === "bigint") {
159
- stringValue = (value as bigint).toString();
225
+ stringValue = `[BigInt: ${(value as bigint).toString()}]`;
160
226
  } else if (typeofValue === "symbol") {
161
227
  stringValue = (value as symbol).toString();
162
228
  } else if (value instanceof Set) {
@@ -175,6 +241,12 @@ function internalFormatValue(
175
241
  stringValue = "{WeakMap...}";
176
242
  } else if (value instanceof WeakSet) {
177
243
  stringValue = "{WeakSet...}";
244
+ } else if (value instanceof Date) {
245
+ stringValue = `[Date: ${value.toISOString()}]`;
246
+ } else if (value instanceof RegExp) {
247
+ stringValue = `[RegExp: ${value.toString()}]`;
248
+ } else if (typeof value === "function") {
249
+ stringValue = `[Function: ${value.name}]`;
178
250
  } else {
179
251
  stringValue = tryStringify(value);
180
252
  }
@@ -196,7 +268,7 @@ const internalFormatKey: FormatKey<string> = (
196
268
  ): FormattedKey => {
197
269
  return {
198
270
  stringKey: `${key}: `,
199
- formattedKey: `${styleFn(["gray-light", "bold"], `${key}:`)} `,
271
+ formattedKey: `${styleFn(["dim", "bold"], `${key}:`)} `,
200
272
  };
201
273
  };
202
274
 
@@ -221,7 +293,7 @@ const internalFormatMapKey: FormatKey<unknown> = (
221
293
  );
222
294
  return {
223
295
  stringKey: `${stringValue} => `,
224
- formattedKey: `${styleFn(["gray-light", "bold"], `${formattedValue}:`)} `,
296
+ formattedKey: `${styleFn(["dim", "bold"], `${formattedValue}:`)} `,
225
297
  };
226
298
  };
227
299
 
@@ -11,9 +11,9 @@ export function formatRecordToString<T extends Metadata>(
11
11
  const parts: string[] = [];
12
12
 
13
13
  if (record.displayName) {
14
- parts.push(style(["gray-light"], record.displayName));
14
+ parts.push(style(["dim"], record.displayName));
15
15
  } else if (record.key) {
16
- parts.push(style(["gray-light"], record.key));
16
+ parts.push(style(["dim"], record.key));
17
17
  }
18
18
 
19
19
  if (record.datetime) {
@@ -0,0 +1,15 @@
1
+ /* eslint sort-keys: error */
2
+
3
+ export const formatStyles = {
4
+ bigint: ["yellow", "bold"],
5
+ boolean: ["green"],
6
+ date: ["magenta"],
7
+ error: ["red"],
8
+ function: ["blue"],
9
+ null: ["bold"],
10
+ number: ["yellow"],
11
+ regexp: ["magenta"],
12
+ string: ["orange"],
13
+ symbol: ["magenta"],
14
+ undefined: ["dim"],
15
+ };
@@ -1,7 +1,5 @@
1
1
  export const styleToHexColor = {
2
2
  orange: "ff5f00",
3
- grayLight: "808080",
4
- "gray-light": "808080",
5
3
  } as const;
6
4
 
7
5
  export type StyleToHexColor = Readonly<
@@ -31,6 +31,7 @@ export const styleToHtmlStyleThemeLight = {
31
31
  cyan: { open: "color: #00cfd8", close: "color: currentcolor" },
32
32
  white: { open: "color: white", close: "color: currentcolor" },
33
33
  gray: { open: "color: gray", close: "color: currentcolor" },
34
+ dim: { open: "color: #808080", close: "color: currentcolor" },
34
35
 
35
36
  bgBlack: { open: "background: black", close: "background: initial" },
36
37
  bgRed: { open: "background: #ff0020", close: "background: initial" },
@@ -45,14 +46,6 @@ export const styleToHtmlStyleThemeLight = {
45
46
  open: `color: #${styleToHexColor.orange}`,
46
47
  close: "color: currentcolor",
47
48
  },
48
- grayLight: {
49
- open: `color: #${styleToHexColor.grayLight}`,
50
- close: "color: currentcolor",
51
- },
52
- "gray-light": {
53
- open: `color: #${styleToHexColor.grayLight}`,
54
- close: "color: currentcolor",
55
- },
56
49
  } as const;
57
50
 
58
51
  export type StyleToHtmlStyle = Readonly<
@@ -22,6 +22,6 @@ test("format simple message", () => {
22
22
  datetime: new Date(2000, 1, 1, 1, 1, 1),
23
23
  }).replace(/\u001B/g, "ESC"),
24
24
  ).toBe(
25
- "ESC[38;5;244mtestESC[39m ESC[1mESC[90m01:01:01ESC[39mESC[22m ESC[90m• testESC[39m",
25
+ "ESC[2mtestESC[22m ESC[1mESC[90m01:01:01ESC[39mESC[22m ESC[90m• testESC[39m",
26
26
  );
27
27
  });
@@ -22,6 +22,7 @@ const ansiStyles: AnsiStyles = {
22
22
  cyan: ansi.cyan,
23
23
  white: ansi.white,
24
24
  gray: ansi.gray,
25
+ dim: ansi.dim,
25
26
 
26
27
  bgBlack: ansi.bgBlack,
27
28
  bgRed: ansi.bgRed,
@@ -40,10 +41,6 @@ const ansiStyles: AnsiStyles = {
40
41
  open: ansi.color.ansi256(ansi.hexToAnsi256(styleToHexColor.orange)),
41
42
  close: ansi.color.close,
42
43
  },
43
- "gray-light": {
44
- open: ansi.color.ansi256(ansi.hexToAnsi256(styleToHexColor["gray-light"])),
45
- close: ansi.color.close,
46
- },
47
44
  };
48
45
 
49
46
  export function style(styles: Styles, string: string): string {
package/src/index.ts CHANGED
@@ -17,6 +17,7 @@ export { BrowserConsoleHandler } from "./handlers/BrowserConsoleHandler";
17
17
  export { ConsoleHandler } from "./handlers/ConsoleHandler";
18
18
  export { ConsoleCLIHandler } from "./handlers/ConsoleCLIHandler";
19
19
  export { LoggerCLI } from "./loggers/LoggerCLI";
20
+ export { formatStyles } from "./formatter-utils/formatStyles";
20
21
 
21
22
  /**
22
23
  * listen to uncaughtException and unhandledRejection