@visulima/pail 4.0.0-alpha.1 → 4.0.0-alpha.11

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.
Files changed (91) hide show
  1. package/CHANGELOG.md +204 -0
  2. package/LICENSE.md +434 -52
  3. package/README.md +323 -0
  4. package/dist/error.d.ts +104 -0
  5. package/dist/error.js +76 -0
  6. package/dist/index.browser.d.ts +3 -1
  7. package/dist/index.browser.js +1490 -3
  8. package/dist/index.server.d.ts +3 -5
  9. package/dist/index.server.js +2380 -110
  10. package/dist/middleware/elysia.d.ts +71 -0
  11. package/dist/middleware/elysia.js +70 -0
  12. package/dist/middleware/express.d.ts +86 -0
  13. package/dist/middleware/express.js +29 -0
  14. package/dist/middleware/fastify.d.ts +81 -0
  15. package/dist/middleware/fastify.js +46 -0
  16. package/dist/middleware/hono.d.ts +85 -0
  17. package/dist/middleware/hono.js +33 -0
  18. package/dist/middleware/next/handler.d.ts +36 -0
  19. package/dist/middleware/next/handler.js +53 -0
  20. package/dist/middleware/next/middleware.d.ts +59 -0
  21. package/dist/middleware/next/storage.d.ts +14 -0
  22. package/dist/middleware/shared/create-middleware-logger.d.ts +82 -0
  23. package/dist/middleware/shared/headers.d.ts +14 -0
  24. package/dist/middleware/shared/routes.d.ts +30 -0
  25. package/dist/middleware/shared/storage.d.ts +29 -0
  26. package/dist/middleware/sveltekit.d.ts +123 -0
  27. package/dist/middleware/sveltekit.js +43 -0
  28. package/dist/object-tree.d.ts +2 -2
  29. package/dist/object-tree.js +7 -7
  30. package/dist/packem_shared/{AbstractJsonReporter-BaZ33PlE.js → AbstractJsonReporter-BO8Calb4.js} +112 -32
  31. package/dist/packem_shared/AbstractJsonReporter-nOj0Ft1F.js +284 -0
  32. package/dist/packem_shared/{JsonReporter-BRw4skd5.js → JsonReporter-CCmj7oYL.js} +2 -2
  33. package/dist/packem_shared/{JsonReporter-VzgyLEYz.js → JsonReporter-Ck2PIAEw.js} +2 -2
  34. package/dist/packem_shared/PrettyReporter-BCvyNzXO.js +2720 -0
  35. package/dist/packem_shared/{PrettyReporter-DySIXBjQ.js → PrettyReporter-BtTr13Ha.js} +55 -11
  36. package/dist/packem_shared/abstract-pretty-reporter-CXAKYCb8.js +2635 -0
  37. package/dist/packem_shared/constants-B1RjD_ps.js +99 -0
  38. package/dist/packem_shared/createPailError-B_sgL0nF.js +76 -0
  39. package/dist/packem_shared/headers-BxHWM6KI.js +127 -0
  40. package/dist/packem_shared/{index-BomQ3E6J.js → index-Bx3-C0j9.js} +29 -21
  41. package/dist/packem_shared/pailMiddleware-Ci88geIF.js +24 -0
  42. package/dist/packem_shared/storage-D0vqz8OX.js +36 -0
  43. package/dist/packem_shared/{InteractiveStreamHook-DiSubbJ1.js → useLogger-D0rU3lcX.js} +13 -1
  44. package/dist/packem_shared/{write-console-log-based-on-level-DBmRYXpj.js → write-console-log-based-on-level-ree2lDPw.js} +5 -4
  45. package/dist/packem_shared/{write-stream-BG8fhcs3.js → write-stream-MDqyXmc_.js} +1 -1
  46. package/dist/pail.browser.d.ts +1 -1
  47. package/dist/pail.server.d.ts +1 -76
  48. package/dist/processor/caller/caller-processor.js +1 -1
  49. package/dist/processor/environment-processor.d.ts +124 -0
  50. package/dist/processor/environment-processor.js +89 -0
  51. package/dist/processor/message-formatter-processor.d.ts +2 -3
  52. package/dist/processor/message-formatter-processor.js +654 -5
  53. package/dist/processor/opentelemetry-processor.js +4 -4
  54. package/dist/processor/redact-processor.d.ts +1 -1
  55. package/dist/processor/redact-processor.js +2 -1
  56. package/dist/processor/sampling-processor.d.ts +111 -0
  57. package/dist/processor/sampling-processor.js +59 -0
  58. package/dist/reporter/file/json-file-reporter.js +1 -1
  59. package/dist/reporter/http/abstract-http-reporter.js +23 -26
  60. package/dist/reporter/http/http-reporter.edge-light.js +134 -57
  61. package/dist/reporter/json/abstract-json-reporter.d.ts +1 -1
  62. package/dist/reporter/json/index.browser.js +2 -2
  63. package/dist/reporter/json/index.js +2 -2
  64. package/dist/reporter/pretty/index.browser.js +1 -1
  65. package/dist/reporter/pretty/index.js +1 -1
  66. package/dist/reporter/pretty/pretty-reporter.server.d.ts +1 -1
  67. package/dist/reporter/raw/raw-reporter.server.d.ts +1 -1
  68. package/dist/reporter/simple/simple-reporter.server.d.ts +1 -1
  69. package/dist/reporter/simple/simple-reporter.server.js +8 -12
  70. package/dist/types.d.ts +4 -4
  71. package/dist/utils/write-console-log-based-on-level.d.ts +1 -1
  72. package/dist/wide-event.d.ts +300 -0
  73. package/dist/wide-event.js +284 -0
  74. package/package.json +73 -20
  75. package/dist/interactive/index.d.ts +0 -2
  76. package/dist/interactive/index.js +0 -2
  77. package/dist/interactive/interactive-manager.d.ts +0 -108
  78. package/dist/interactive/interactive-stream-hook.d.ts +0 -68
  79. package/dist/packem_shared/InteractiveManager-CZ85hGNW.js +0 -172
  80. package/dist/packem_shared/PrettyReporter-DgZB2eBG.js +0 -222
  81. package/dist/packem_shared/abstract-pretty-reporter-Di_sdm2r.js +0 -50
  82. package/dist/packem_shared/format-label-De49vNPd.js +0 -1193
  83. package/dist/packem_shared/get-longest-label-C9PWeyKq.js +0 -9
  84. package/dist/packem_shared/index-DqKWykfa.js +0 -1146
  85. package/dist/packem_shared/interactive-stream-hook-DG4BtN12.js +0 -141
  86. package/dist/packem_shared/pail.browser-u2CSR_af.js +0 -1427
  87. package/dist/progress-bar.d.ts +0 -136
  88. package/dist/progress-bar.js +0 -404
  89. package/dist/spinner.d.ts +0 -220
  90. package/dist/spinner.js +0 -2150
  91. package/dist/utils/ansi-escapes.d.ts +0 -4
@@ -9,18 +9,1464 @@ const {
9
9
  stderr,
10
10
  env
11
11
  } = __cjs_getProcess;
12
- import InteractiveManager from './packem_shared/InteractiveManager-CZ85hGNW.js';
13
- import { I as InteractiveStreamHook, c as clearTerminal } from './packem_shared/interactive-stream-hook-DG4BtN12.js';
14
- import { a as PailBrowserImpl, m as mergeTypes, b as arrayify } from './packem_shared/pail.browser-u2CSR_af.js';
15
- import { ProgressBar, applyStyleToOptions, MultiProgressBar } from './progress-bar.js';
16
- export { getBarChar } from './progress-bar.js';
17
- import { i as inspect } from './packem_shared/format-label-De49vNPd.js';
18
- import { E as EMPTY_SYMBOL } from './packem_shared/constants-omsTHUWB.js';
19
- import { w as writeStream } from './packem_shared/write-stream-BG8fhcs3.js';
20
- import { Spinner, MultiSpinner } from './spinner.js';
21
- import { g as getLongestLabel } from './packem_shared/get-longest-label-C9PWeyKq.js';
22
- import MessageFormatterProcessor from './processor/message-formatter-processor.js';
23
- import { PrettyReporter } from './packem_shared/PrettyReporter-DgZB2eBG.js';
12
+ import { InteractiveManager, InteractiveStreamHook } from '@visulima/interactive-manager';
13
+ import { g as getLongestLabel, E as EXTENDED_RFC_5424_LOG_LEVELS, a as EMPTY_SYMBOL, L as LOG_TYPES, i as inspect, w as writeStream, A as AbstractPrettyReporter, d as defaultInspectorConfig, t as terminalSize, b as getLongestBadge, c as getStringWidth, f as formatLabel, e as wordWrap, r as renderError, W as WrapMode } from './packem_shared/abstract-pretty-reporter-CXAKYCb8.js';
14
+ import colorize, { red, greenBright, cyan, green, grey, bgGrey, underline, white } from '@visulima/colorize';
15
+ export { PailError, createPailError } from './packem_shared/createPailError-B_sgL0nF.js';
16
+
17
+ const ESC = "\x1B";
18
+ const CSI = `${ESC}[`;
19
+
20
+ const isBrowser = typeof globalThis !== "undefined" && typeof globalThis.window === "object" && globalThis.window.document !== void 0;
21
+ const OSTYPE_REGEX = /^(?:msys|cygwin)$/;
22
+ const isWindows = !isBrowser && (process.platform === "win32" || OSTYPE_REGEX.test(process.env.OSTYPE));
23
+
24
+ var EraseDisplayMode = /* @__PURE__ */ ((EraseDisplayMode2) => {
25
+ EraseDisplayMode2[EraseDisplayMode2["ToEnd"] = 0] = "ToEnd";
26
+ EraseDisplayMode2[EraseDisplayMode2["ToBeginning"] = 1] = "ToBeginning";
27
+ EraseDisplayMode2[EraseDisplayMode2["EntireScreen"] = 2] = "EntireScreen";
28
+ EraseDisplayMode2[EraseDisplayMode2["EntireScreenAndScrollback"] = 3] = "EntireScreenAndScrollback";
29
+ return EraseDisplayMode2;
30
+ })(EraseDisplayMode || {});
31
+ const eraseDisplay = (mode) => {
32
+ const validMode = mode >= 0 && mode <= 3 ? mode : 0;
33
+ return `${CSI}${validMode === 0 ? "" : String(validMode)}J`;
34
+ };
35
+
36
+ const resetTerminal = isWindows ? `${eraseDisplay(EraseDisplayMode.EntireScreen)}${CSI}0f` : `${eraseDisplay(EraseDisplayMode.EntireScreen)}${eraseDisplay(EraseDisplayMode.EntireScreenAndScrollback)}${CSI}H${ESC}c`;
37
+
38
+ function getDefaultExportFromCjs(x) {
39
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
40
+ }
41
+
42
+ var safeStableStringify = {exports: {}};
43
+
44
+ var hasRequiredSafeStableStringify;
45
+
46
+ function requireSafeStableStringify () {
47
+ if (hasRequiredSafeStableStringify) return safeStableStringify.exports;
48
+ hasRequiredSafeStableStringify = 1;
49
+ (function (module, exports$1) {
50
+ const { hasOwnProperty } = Object.prototype;
51
+ const stringify = configure();
52
+ stringify.configure = configure;
53
+ stringify.stringify = stringify;
54
+ stringify.default = stringify;
55
+ exports$1.stringify = stringify;
56
+ exports$1.configure = configure;
57
+ module.exports = stringify;
58
+ const strEscapeSequencesRegExp = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]/;
59
+ function strEscape(str) {
60
+ if (str.length < 5e3 && !strEscapeSequencesRegExp.test(str)) {
61
+ return `"${str}"`;
62
+ }
63
+ return JSON.stringify(str);
64
+ }
65
+ function sort(array, comparator) {
66
+ if (array.length > 200 || comparator) {
67
+ return array.sort(comparator);
68
+ }
69
+ for (let i = 1; i < array.length; i++) {
70
+ const currentValue = array[i];
71
+ let position = i;
72
+ while (position !== 0 && array[position - 1] > currentValue) {
73
+ array[position] = array[position - 1];
74
+ position--;
75
+ }
76
+ array[position] = currentValue;
77
+ }
78
+ return array;
79
+ }
80
+ const typedArrayPrototypeGetSymbolToStringTag = Object.getOwnPropertyDescriptor(
81
+ Object.getPrototypeOf(
82
+ Object.getPrototypeOf(
83
+ new Int8Array()
84
+ )
85
+ ),
86
+ Symbol.toStringTag
87
+ ).get;
88
+ function isTypedArrayWithEntries(value) {
89
+ return typedArrayPrototypeGetSymbolToStringTag.call(value) !== void 0 && value.length !== 0;
90
+ }
91
+ function stringifyTypedArray(array, separator, maximumBreadth) {
92
+ if (array.length < maximumBreadth) {
93
+ maximumBreadth = array.length;
94
+ }
95
+ const whitespace = separator === "," ? "" : " ";
96
+ let res = `"0":${whitespace}${array[0]}`;
97
+ for (let i = 1; i < maximumBreadth; i++) {
98
+ res += `${separator}"${i}":${whitespace}${array[i]}`;
99
+ }
100
+ return res;
101
+ }
102
+ function getCircularValueOption(options) {
103
+ if (hasOwnProperty.call(options, "circularValue")) {
104
+ const circularValue = options.circularValue;
105
+ if (typeof circularValue === "string") {
106
+ return `"${circularValue}"`;
107
+ }
108
+ if (circularValue == null) {
109
+ return circularValue;
110
+ }
111
+ if (circularValue === Error || circularValue === TypeError) {
112
+ return {
113
+ toString() {
114
+ throw new TypeError("Converting circular structure to JSON");
115
+ }
116
+ };
117
+ }
118
+ throw new TypeError('The "circularValue" argument must be of type string or the value null or undefined');
119
+ }
120
+ return '"[Circular]"';
121
+ }
122
+ function getDeterministicOption(options) {
123
+ let value;
124
+ if (hasOwnProperty.call(options, "deterministic")) {
125
+ value = options.deterministic;
126
+ if (typeof value !== "boolean" && typeof value !== "function") {
127
+ throw new TypeError('The "deterministic" argument must be of type boolean or comparator function');
128
+ }
129
+ }
130
+ return value === void 0 ? true : value;
131
+ }
132
+ function getBooleanOption(options, key) {
133
+ let value;
134
+ if (hasOwnProperty.call(options, key)) {
135
+ value = options[key];
136
+ if (typeof value !== "boolean") {
137
+ throw new TypeError(`The "${key}" argument must be of type boolean`);
138
+ }
139
+ }
140
+ return value === void 0 ? true : value;
141
+ }
142
+ function getPositiveIntegerOption(options, key) {
143
+ let value;
144
+ if (hasOwnProperty.call(options, key)) {
145
+ value = options[key];
146
+ if (typeof value !== "number") {
147
+ throw new TypeError(`The "${key}" argument must be of type number`);
148
+ }
149
+ if (!Number.isInteger(value)) {
150
+ throw new TypeError(`The "${key}" argument must be an integer`);
151
+ }
152
+ if (value < 1) {
153
+ throw new RangeError(`The "${key}" argument must be >= 1`);
154
+ }
155
+ }
156
+ return value === void 0 ? Infinity : value;
157
+ }
158
+ function getItemCount(number) {
159
+ if (number === 1) {
160
+ return "1 item";
161
+ }
162
+ return `${number} items`;
163
+ }
164
+ function getUniqueReplacerSet(replacerArray) {
165
+ const replacerSet = /* @__PURE__ */ new Set();
166
+ for (const value of replacerArray) {
167
+ if (typeof value === "string" || typeof value === "number") {
168
+ replacerSet.add(String(value));
169
+ }
170
+ }
171
+ return replacerSet;
172
+ }
173
+ function getStrictOption(options) {
174
+ if (hasOwnProperty.call(options, "strict")) {
175
+ const value = options.strict;
176
+ if (typeof value !== "boolean") {
177
+ throw new TypeError('The "strict" argument must be of type boolean');
178
+ }
179
+ if (value) {
180
+ return (value2) => {
181
+ let message = `Object can not safely be stringified. Received type ${typeof value2}`;
182
+ if (typeof value2 !== "function") message += ` (${value2.toString()})`;
183
+ throw new Error(message);
184
+ };
185
+ }
186
+ }
187
+ }
188
+ function configure(options) {
189
+ options = { ...options };
190
+ const fail = getStrictOption(options);
191
+ if (fail) {
192
+ if (options.bigint === void 0) {
193
+ options.bigint = false;
194
+ }
195
+ if (!("circularValue" in options)) {
196
+ options.circularValue = Error;
197
+ }
198
+ }
199
+ const circularValue = getCircularValueOption(options);
200
+ const bigint = getBooleanOption(options, "bigint");
201
+ const deterministic = getDeterministicOption(options);
202
+ const comparator = typeof deterministic === "function" ? deterministic : void 0;
203
+ const maximumDepth = getPositiveIntegerOption(options, "maximumDepth");
204
+ const maximumBreadth = getPositiveIntegerOption(options, "maximumBreadth");
205
+ function stringifyFnReplacer(key, parent, stack, replacer, spacer, indentation) {
206
+ let value = parent[key];
207
+ if (typeof value === "object" && value !== null && typeof value.toJSON === "function") {
208
+ value = value.toJSON(key);
209
+ }
210
+ value = replacer.call(parent, key, value);
211
+ switch (typeof value) {
212
+ case "string":
213
+ return strEscape(value);
214
+ case "object": {
215
+ if (value === null) {
216
+ return "null";
217
+ }
218
+ if (stack.indexOf(value) !== -1) {
219
+ return circularValue;
220
+ }
221
+ let res = "";
222
+ let join = ",";
223
+ const originalIndentation = indentation;
224
+ if (Array.isArray(value)) {
225
+ if (value.length === 0) {
226
+ return "[]";
227
+ }
228
+ if (maximumDepth < stack.length + 1) {
229
+ return '"[Array]"';
230
+ }
231
+ stack.push(value);
232
+ if (spacer !== "") {
233
+ indentation += spacer;
234
+ res += `
235
+ ${indentation}`;
236
+ join = `,
237
+ ${indentation}`;
238
+ }
239
+ const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
240
+ let i = 0;
241
+ for (; i < maximumValuesToStringify - 1; i++) {
242
+ const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
243
+ res += tmp2 !== void 0 ? tmp2 : "null";
244
+ res += join;
245
+ }
246
+ const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
247
+ res += tmp !== void 0 ? tmp : "null";
248
+ if (value.length - 1 > maximumBreadth) {
249
+ const removedKeys = value.length - maximumBreadth - 1;
250
+ res += `${join}"... ${getItemCount(removedKeys)} not stringified"`;
251
+ }
252
+ if (spacer !== "") {
253
+ res += `
254
+ ${originalIndentation}`;
255
+ }
256
+ stack.pop();
257
+ return `[${res}]`;
258
+ }
259
+ let keys = Object.keys(value);
260
+ const keyLength = keys.length;
261
+ if (keyLength === 0) {
262
+ return "{}";
263
+ }
264
+ if (maximumDepth < stack.length + 1) {
265
+ return '"[Object]"';
266
+ }
267
+ let whitespace = "";
268
+ let separator = "";
269
+ if (spacer !== "") {
270
+ indentation += spacer;
271
+ join = `,
272
+ ${indentation}`;
273
+ whitespace = " ";
274
+ }
275
+ const maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
276
+ if (deterministic && !isTypedArrayWithEntries(value)) {
277
+ keys = sort(keys, comparator);
278
+ }
279
+ stack.push(value);
280
+ for (let i = 0; i < maximumPropertiesToStringify; i++) {
281
+ const key2 = keys[i];
282
+ const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
283
+ if (tmp !== void 0) {
284
+ res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
285
+ separator = join;
286
+ }
287
+ }
288
+ if (keyLength > maximumBreadth) {
289
+ const removedKeys = keyLength - maximumBreadth;
290
+ res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
291
+ separator = join;
292
+ }
293
+ if (spacer !== "" && separator.length > 1) {
294
+ res = `
295
+ ${indentation}${res}
296
+ ${originalIndentation}`;
297
+ }
298
+ stack.pop();
299
+ return `{${res}}`;
300
+ }
301
+ case "number":
302
+ return isFinite(value) ? String(value) : fail ? fail(value) : "null";
303
+ case "boolean":
304
+ return value === true ? "true" : "false";
305
+ case "undefined":
306
+ return void 0;
307
+ case "bigint":
308
+ if (bigint) {
309
+ return String(value);
310
+ }
311
+ // fallthrough
312
+ default:
313
+ return fail ? fail(value) : void 0;
314
+ }
315
+ }
316
+ function stringifyArrayReplacer(key, value, stack, replacer, spacer, indentation) {
317
+ if (typeof value === "object" && value !== null && typeof value.toJSON === "function") {
318
+ value = value.toJSON(key);
319
+ }
320
+ switch (typeof value) {
321
+ case "string":
322
+ return strEscape(value);
323
+ case "object": {
324
+ if (value === null) {
325
+ return "null";
326
+ }
327
+ if (stack.indexOf(value) !== -1) {
328
+ return circularValue;
329
+ }
330
+ const originalIndentation = indentation;
331
+ let res = "";
332
+ let join = ",";
333
+ if (Array.isArray(value)) {
334
+ if (value.length === 0) {
335
+ return "[]";
336
+ }
337
+ if (maximumDepth < stack.length + 1) {
338
+ return '"[Array]"';
339
+ }
340
+ stack.push(value);
341
+ if (spacer !== "") {
342
+ indentation += spacer;
343
+ res += `
344
+ ${indentation}`;
345
+ join = `,
346
+ ${indentation}`;
347
+ }
348
+ const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
349
+ let i = 0;
350
+ for (; i < maximumValuesToStringify - 1; i++) {
351
+ const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
352
+ res += tmp2 !== void 0 ? tmp2 : "null";
353
+ res += join;
354
+ }
355
+ const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
356
+ res += tmp !== void 0 ? tmp : "null";
357
+ if (value.length - 1 > maximumBreadth) {
358
+ const removedKeys = value.length - maximumBreadth - 1;
359
+ res += `${join}"... ${getItemCount(removedKeys)} not stringified"`;
360
+ }
361
+ if (spacer !== "") {
362
+ res += `
363
+ ${originalIndentation}`;
364
+ }
365
+ stack.pop();
366
+ return `[${res}]`;
367
+ }
368
+ stack.push(value);
369
+ let whitespace = "";
370
+ if (spacer !== "") {
371
+ indentation += spacer;
372
+ join = `,
373
+ ${indentation}`;
374
+ whitespace = " ";
375
+ }
376
+ let separator = "";
377
+ for (const key2 of replacer) {
378
+ const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
379
+ if (tmp !== void 0) {
380
+ res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
381
+ separator = join;
382
+ }
383
+ }
384
+ if (spacer !== "" && separator.length > 1) {
385
+ res = `
386
+ ${indentation}${res}
387
+ ${originalIndentation}`;
388
+ }
389
+ stack.pop();
390
+ return `{${res}}`;
391
+ }
392
+ case "number":
393
+ return isFinite(value) ? String(value) : fail ? fail(value) : "null";
394
+ case "boolean":
395
+ return value === true ? "true" : "false";
396
+ case "undefined":
397
+ return void 0;
398
+ case "bigint":
399
+ if (bigint) {
400
+ return String(value);
401
+ }
402
+ // fallthrough
403
+ default:
404
+ return fail ? fail(value) : void 0;
405
+ }
406
+ }
407
+ function stringifyIndent(key, value, stack, spacer, indentation) {
408
+ switch (typeof value) {
409
+ case "string":
410
+ return strEscape(value);
411
+ case "object": {
412
+ if (value === null) {
413
+ return "null";
414
+ }
415
+ if (typeof value.toJSON === "function") {
416
+ value = value.toJSON(key);
417
+ if (typeof value !== "object") {
418
+ return stringifyIndent(key, value, stack, spacer, indentation);
419
+ }
420
+ if (value === null) {
421
+ return "null";
422
+ }
423
+ }
424
+ if (stack.indexOf(value) !== -1) {
425
+ return circularValue;
426
+ }
427
+ const originalIndentation = indentation;
428
+ if (Array.isArray(value)) {
429
+ if (value.length === 0) {
430
+ return "[]";
431
+ }
432
+ if (maximumDepth < stack.length + 1) {
433
+ return '"[Array]"';
434
+ }
435
+ stack.push(value);
436
+ indentation += spacer;
437
+ let res2 = `
438
+ ${indentation}`;
439
+ const join2 = `,
440
+ ${indentation}`;
441
+ const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
442
+ let i = 0;
443
+ for (; i < maximumValuesToStringify - 1; i++) {
444
+ const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
445
+ res2 += tmp2 !== void 0 ? tmp2 : "null";
446
+ res2 += join2;
447
+ }
448
+ const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
449
+ res2 += tmp !== void 0 ? tmp : "null";
450
+ if (value.length - 1 > maximumBreadth) {
451
+ const removedKeys = value.length - maximumBreadth - 1;
452
+ res2 += `${join2}"... ${getItemCount(removedKeys)} not stringified"`;
453
+ }
454
+ res2 += `
455
+ ${originalIndentation}`;
456
+ stack.pop();
457
+ return `[${res2}]`;
458
+ }
459
+ let keys = Object.keys(value);
460
+ const keyLength = keys.length;
461
+ if (keyLength === 0) {
462
+ return "{}";
463
+ }
464
+ if (maximumDepth < stack.length + 1) {
465
+ return '"[Object]"';
466
+ }
467
+ indentation += spacer;
468
+ const join = `,
469
+ ${indentation}`;
470
+ let res = "";
471
+ let separator = "";
472
+ let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
473
+ if (isTypedArrayWithEntries(value)) {
474
+ res += stringifyTypedArray(value, join, maximumBreadth);
475
+ keys = keys.slice(value.length);
476
+ maximumPropertiesToStringify -= value.length;
477
+ separator = join;
478
+ }
479
+ if (deterministic) {
480
+ keys = sort(keys, comparator);
481
+ }
482
+ stack.push(value);
483
+ for (let i = 0; i < maximumPropertiesToStringify; i++) {
484
+ const key2 = keys[i];
485
+ const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
486
+ if (tmp !== void 0) {
487
+ res += `${separator}${strEscape(key2)}: ${tmp}`;
488
+ separator = join;
489
+ }
490
+ }
491
+ if (keyLength > maximumBreadth) {
492
+ const removedKeys = keyLength - maximumBreadth;
493
+ res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
494
+ separator = join;
495
+ }
496
+ if (separator !== "") {
497
+ res = `
498
+ ${indentation}${res}
499
+ ${originalIndentation}`;
500
+ }
501
+ stack.pop();
502
+ return `{${res}}`;
503
+ }
504
+ case "number":
505
+ return isFinite(value) ? String(value) : fail ? fail(value) : "null";
506
+ case "boolean":
507
+ return value === true ? "true" : "false";
508
+ case "undefined":
509
+ return void 0;
510
+ case "bigint":
511
+ if (bigint) {
512
+ return String(value);
513
+ }
514
+ // fallthrough
515
+ default:
516
+ return fail ? fail(value) : void 0;
517
+ }
518
+ }
519
+ function stringifySimple(key, value, stack) {
520
+ switch (typeof value) {
521
+ case "string":
522
+ return strEscape(value);
523
+ case "object": {
524
+ if (value === null) {
525
+ return "null";
526
+ }
527
+ if (typeof value.toJSON === "function") {
528
+ value = value.toJSON(key);
529
+ if (typeof value !== "object") {
530
+ return stringifySimple(key, value, stack);
531
+ }
532
+ if (value === null) {
533
+ return "null";
534
+ }
535
+ }
536
+ if (stack.indexOf(value) !== -1) {
537
+ return circularValue;
538
+ }
539
+ let res = "";
540
+ const hasLength = value.length !== void 0;
541
+ if (hasLength && Array.isArray(value)) {
542
+ if (value.length === 0) {
543
+ return "[]";
544
+ }
545
+ if (maximumDepth < stack.length + 1) {
546
+ return '"[Array]"';
547
+ }
548
+ stack.push(value);
549
+ const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
550
+ let i = 0;
551
+ for (; i < maximumValuesToStringify - 1; i++) {
552
+ const tmp2 = stringifySimple(String(i), value[i], stack);
553
+ res += tmp2 !== void 0 ? tmp2 : "null";
554
+ res += ",";
555
+ }
556
+ const tmp = stringifySimple(String(i), value[i], stack);
557
+ res += tmp !== void 0 ? tmp : "null";
558
+ if (value.length - 1 > maximumBreadth) {
559
+ const removedKeys = value.length - maximumBreadth - 1;
560
+ res += `,"... ${getItemCount(removedKeys)} not stringified"`;
561
+ }
562
+ stack.pop();
563
+ return `[${res}]`;
564
+ }
565
+ let keys = Object.keys(value);
566
+ const keyLength = keys.length;
567
+ if (keyLength === 0) {
568
+ return "{}";
569
+ }
570
+ if (maximumDepth < stack.length + 1) {
571
+ return '"[Object]"';
572
+ }
573
+ let separator = "";
574
+ let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
575
+ if (hasLength && isTypedArrayWithEntries(value)) {
576
+ res += stringifyTypedArray(value, ",", maximumBreadth);
577
+ keys = keys.slice(value.length);
578
+ maximumPropertiesToStringify -= value.length;
579
+ separator = ",";
580
+ }
581
+ if (deterministic) {
582
+ keys = sort(keys, comparator);
583
+ }
584
+ stack.push(value);
585
+ for (let i = 0; i < maximumPropertiesToStringify; i++) {
586
+ const key2 = keys[i];
587
+ const tmp = stringifySimple(key2, value[key2], stack);
588
+ if (tmp !== void 0) {
589
+ res += `${separator}${strEscape(key2)}:${tmp}`;
590
+ separator = ",";
591
+ }
592
+ }
593
+ if (keyLength > maximumBreadth) {
594
+ const removedKeys = keyLength - maximumBreadth;
595
+ res += `${separator}"...":"${getItemCount(removedKeys)} not stringified"`;
596
+ }
597
+ stack.pop();
598
+ return `{${res}}`;
599
+ }
600
+ case "number":
601
+ return isFinite(value) ? String(value) : fail ? fail(value) : "null";
602
+ case "boolean":
603
+ return value === true ? "true" : "false";
604
+ case "undefined":
605
+ return void 0;
606
+ case "bigint":
607
+ if (bigint) {
608
+ return String(value);
609
+ }
610
+ // fallthrough
611
+ default:
612
+ return fail ? fail(value) : void 0;
613
+ }
614
+ }
615
+ function stringify2(value, replacer, space) {
616
+ if (arguments.length > 1) {
617
+ let spacer = "";
618
+ if (typeof space === "number") {
619
+ spacer = " ".repeat(Math.min(space, 10));
620
+ } else if (typeof space === "string") {
621
+ spacer = space.slice(0, 10);
622
+ }
623
+ if (replacer != null) {
624
+ if (typeof replacer === "function") {
625
+ return stringifyFnReplacer("", { "": value }, [], replacer, spacer, "");
626
+ }
627
+ if (Array.isArray(replacer)) {
628
+ return stringifyArrayReplacer("", value, [], getUniqueReplacerSet(replacer), spacer, "");
629
+ }
630
+ }
631
+ if (spacer.length !== 0) {
632
+ return stringifyIndent("", value, [], spacer, "");
633
+ }
634
+ }
635
+ return stringifySimple("", value, []);
636
+ }
637
+ return stringify2;
638
+ }
639
+ } (safeStableStringify, safeStableStringify.exports));
640
+ return safeStableStringify.exports;
641
+ }
642
+
643
+ var safeStableStringifyExports = requireSafeStableStringify();
644
+ const cjsModule = /*@__PURE__*/getDefaultExportFromCjs(safeStableStringifyExports);
645
+
646
+ const configure = cjsModule.configure;
647
+
648
+ const writeConsoleLogBasedOnLevel = (level) => {
649
+ const c = console;
650
+ if (level === "error") {
651
+ return c.__error ?? console.error;
652
+ }
653
+ if (level === "warn") {
654
+ return c.__warn ?? console.warn;
655
+ }
656
+ if (level === "trace") {
657
+ return c.__trace ?? console.trace;
658
+ }
659
+ return c.__log ?? console.log;
660
+ };
661
+
662
+ let RawReporter$1 = class RawReporter {
663
+ // eslint-disable-next-line class-methods-use-this
664
+ log(meta) {
665
+ const { context = [], message, type } = meta;
666
+ const consoleLogFunction = writeConsoleLogBasedOnLevel(type.level);
667
+ consoleLogFunction(message, ...context);
668
+ }
669
+ };
670
+
671
+ const arrayify = (x) => {
672
+ if (x === void 0) {
673
+ return [];
674
+ }
675
+ return Array.isArray(x) ? x : [x];
676
+ };
677
+
678
+ const mergeTypes = (standard, custom) => {
679
+ const types = { ...standard };
680
+ Object.keys(custom).forEach((type) => {
681
+ types[type] = { ...types[type], ...custom[type] };
682
+ });
683
+ return types;
684
+ };
685
+
686
+ const preventLoop = (function_) => {
687
+ let doing = false;
688
+ return function(...args) {
689
+ if (doing) {
690
+ return void 0;
691
+ }
692
+ doing = true;
693
+ try {
694
+ const result = function_.apply(this, args);
695
+ doing = false;
696
+ return result;
697
+ } catch (error) {
698
+ doing = false;
699
+ throw error;
700
+ }
701
+ };
702
+ };
703
+ class PailBrowserImpl {
704
+ timersMap;
705
+ countMap;
706
+ seqTimers;
707
+ lastLog;
708
+ logLevels;
709
+ disabled;
710
+ paused;
711
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
712
+ messageQueue;
713
+ scopeName;
714
+ types;
715
+ longestLabel;
716
+ processors;
717
+ generalLogLevel;
718
+ reporters;
719
+ throttle;
720
+ throttleMin;
721
+ stringify;
722
+ groups;
723
+ startTimerMessage;
724
+ endTimerMessage;
725
+ rawReporter;
726
+ force = {};
727
+ /**
728
+ * Creates a new Pail browser logger instance.
729
+ *
730
+ * Initializes the logger with the provided configuration options,
731
+ * setting up reporters, processors, log levels, and other internal state.
732
+ * @param options Configuration options for the logger
733
+ */
734
+ constructor(options) {
735
+ this.throttle = options.throttle ?? 1e3;
736
+ this.throttleMin = options.throttleMin ?? 5;
737
+ const parentLongestLabel = options.parentLongestLabel;
738
+ const parentTypes = options.parentTypes;
739
+ const parentStringify = options.parentStringify;
740
+ const parentLogLevels = options.parentLogLevels;
741
+ this.stringify = parentStringify ?? configure({
742
+ strict: true
743
+ });
744
+ this.startTimerMessage = options.messages?.timerStart ?? "Initialized timer...";
745
+ this.endTimerMessage = options.messages?.timerEnd ?? "Timer run for:";
746
+ if (parentTypes && parentLongestLabel) {
747
+ this.types = parentTypes;
748
+ this.longestLabel = parentLongestLabel;
749
+ } else {
750
+ this.types = mergeTypes(LOG_TYPES, options.types ?? {});
751
+ this.longestLabel = getLongestLabel(this.types);
752
+ }
753
+ this.logLevels = parentLogLevels && !options.logLevels ? parentLogLevels : { ...EXTENDED_RFC_5424_LOG_LEVELS, ...options.logLevels };
754
+ this.generalLogLevel = this.#normalizeLogLevel(options.logLevel);
755
+ this.reporters = /* @__PURE__ */ new Set();
756
+ this.processors = /* @__PURE__ */ new Set();
757
+ this.disabled = options.disabled ?? false;
758
+ this.paused = false;
759
+ this.messageQueue = [];
760
+ this.scopeName = arrayify(options.scope).filter(Boolean);
761
+ this.timersMap = /* @__PURE__ */ new Map();
762
+ this.countMap = /* @__PURE__ */ new Map();
763
+ this.groups = [];
764
+ this.seqTimers = /* @__PURE__ */ new Set();
765
+ this.lastLog = {};
766
+ this.logger = preventLoop(this.logger.bind(this));
767
+ this.#initializeBoundMethods();
768
+ if (Array.isArray(options.reporters)) {
769
+ this.registerReporters(options.reporters);
770
+ }
771
+ this.rawReporter = this.extendReporter(options.rawReporter ?? new RawReporter$1());
772
+ if (Array.isArray(options.processors)) {
773
+ this.registerProcessors(options.processors);
774
+ }
775
+ }
776
+ /**
777
+ * Initializes bound methods for all logger types.
778
+ *
779
+ * Creates bound methods for both regular and force logging methods.
780
+ * This is separated to allow reuse when types haven't changed.
781
+ */
782
+ #initializeBoundMethods() {
783
+ for (const type in this.types) {
784
+ this[type] = this.logger.bind(this, type, false, false);
785
+ }
786
+ for (const type in this.types) {
787
+ this.force[type] = this.logger.bind(this, type, false, true);
788
+ }
789
+ }
790
+ /**
791
+ * Wraps the global console methods to redirect them through the logger.
792
+ *
793
+ * This method replaces console methods (log, info, warn, error, etc.) with
794
+ * calls to the corresponding logger methods. The original console methods
795
+ * are backed up and can be restored using restoreConsole().
796
+ * @example
797
+ * ```typescript
798
+ * const logger = createPail();
799
+ * logger.wrapConsole();
800
+ *
801
+ * console.log("This will go through the logger");
802
+ * console.error("This too!");
803
+ *
804
+ * logger.restoreConsole(); // Restore original console methods
805
+ * ```
806
+ */
807
+ wrapConsole() {
808
+ for (const type in this.types) {
809
+ if (!console[`__${type}`]) {
810
+ console[`__${type}`] = console[type];
811
+ }
812
+ console[type] = this[type];
813
+ }
814
+ }
815
+ /**
816
+ * Restores the original global console methods.
817
+ *
818
+ * This method restores the console methods that were backed up by wrapConsole().
819
+ * After calling this, console methods will work as they did before wrapping.
820
+ * @example
821
+ * ```typescript
822
+ * const logger = createPail();
823
+ * logger.wrapConsole();
824
+ *
825
+ * // Console methods are now wrapped
826
+ * logger.restoreConsole();
827
+ * // Console methods are restored to original behavior
828
+ * ```
829
+ */
830
+ restoreConsole() {
831
+ for (const type in this.types) {
832
+ if (console[`__${type}`]) {
833
+ console[type] = console[`__${type}`];
834
+ delete console[`__${type}`];
835
+ }
836
+ }
837
+ }
838
+ /**
839
+ * Wraps uncaught exception and unhandled rejection handlers.
840
+ *
841
+ * This method sets up global error handlers that will log uncaught exceptions
842
+ * and unhandled promise rejections through the logger. This is useful for
843
+ * capturing and logging application crashes.
844
+ * @example
845
+ * ```typescript
846
+ * const logger = createPail();
847
+ * logger.wrapException();
848
+ *
849
+ * // Now uncaught errors will be logged
850
+ * throw new Error("This will be logged");
851
+ * ```
852
+ */
853
+ wrapException() {
854
+ {
855
+ process.on("uncaughtException", (error) => {
856
+ this.error(error);
857
+ });
858
+ process.on("unhandledRejection", (error) => {
859
+ this.error(error);
860
+ });
861
+ }
862
+ }
863
+ /**
864
+ * Disables all logging output.
865
+ *
866
+ * When disabled, all log calls will be silently ignored and no output
867
+ * will be produced by any reporters. This can be useful for temporarily
868
+ * suppressing log output in production or during testing.
869
+ * @example
870
+ * ```typescript
871
+ * const logger = createPail();
872
+ * logger.disable();
873
+ * logger.info("This won't be logged"); // Silent
874
+ * logger.enable();
875
+ * logger.info("This will be logged"); // Output produced
876
+ * ```
877
+ */
878
+ disable() {
879
+ this.disabled = true;
880
+ }
881
+ /**
882
+ * Enables logging output.
883
+ *
884
+ * Re-enables logging after it has been disabled. All subsequent log calls
885
+ * will produce output according to the configured reporters.
886
+ * @example
887
+ * ```typescript
888
+ * const logger = createPail();
889
+ * logger.disable();
890
+ * logger.info("This won't be logged");
891
+ * logger.enable(); // Re-enable logging
892
+ * logger.info("This will be logged");
893
+ * ```
894
+ */
895
+ enable() {
896
+ this.disabled = false;
897
+ }
898
+ /**
899
+ * Checks if logging is currently enabled.
900
+ *
901
+ * Returns true if logging is enabled and false if it has been disabled.
902
+ * @returns True if logging is enabled, false if disabled
903
+ * @example
904
+ * ```typescript
905
+ * const logger = createPail();
906
+ * console.log(logger.isEnabled()); // true
907
+ * logger.disable();
908
+ * console.log(logger.isEnabled()); // false
909
+ * ```
910
+ */
911
+ isEnabled() {
912
+ return !this.disabled;
913
+ }
914
+ /**
915
+ * Pauses logging and starts queuing messages.
916
+ *
917
+ * When paused, all log calls will be queued instead of being output immediately.
918
+ * The queued messages will be processed when resume() is called. This is useful
919
+ * for temporarily buffering log output during critical operations.
920
+ * @example
921
+ * ```typescript
922
+ * const logger = createPail();
923
+ * logger.pause();
924
+ * logger.info("This will be queued"); // Queued, not output yet
925
+ * logger.warn("This too"); // Also queued
926
+ * logger.resume(); // Now both messages are output
927
+ * ```
928
+ */
929
+ pause() {
930
+ this.paused = true;
931
+ }
932
+ /**
933
+ * Resumes logging and flushes all queued messages.
934
+ *
935
+ * Processes all messages that were queued during the pause period and
936
+ * resumes normal logging behavior. Messages are output in the order
937
+ * they were originally called.
938
+ * @example
939
+ * ```typescript
940
+ * const logger = createPail();
941
+ * logger.pause();
942
+ * logger.info("Message 1"); // Queued
943
+ * logger.info("Message 2"); // Queued
944
+ * logger.resume(); // Both messages are now output in order
945
+ * logger.info("Message 3"); // Output immediately
946
+ * ```
947
+ */
948
+ resume() {
949
+ this.paused = false;
950
+ const queue = this.messageQueue.splice(0);
951
+ for (let i = 0; i < queue.length; i += 1) {
952
+ const { messageObject, raw, type } = queue[i];
953
+ this.logger(type, raw, false, ...messageObject);
954
+ }
955
+ }
956
+ /**
957
+ * Creates a scoped logger instance.
958
+ *
959
+ * Returns a new logger instance that inherits all configuration but adds
960
+ * the specified scope names to all log messages. This is useful for
961
+ * categorizing logs by component, module, or feature.
962
+ * @template N - The new custom logger type names
963
+ * @param name Scope names to apply to all log messages
964
+ * @returns A new scoped logger instance
965
+ * @throws {Error} If no scope name is provided
966
+ * @example
967
+ * ```typescript
968
+ * const logger = createPail();
969
+ * const scopedLogger = logger.scope("auth", "login");
970
+ * scopedLogger.info("User logged in"); // Will include scope: ["auth", "login"]
971
+ * ```
972
+ */
973
+ scope(...name) {
974
+ if (name.length === 0) {
975
+ throw new Error("No scope name was defined.");
976
+ }
977
+ this.scopeName = name.flat();
978
+ return this;
979
+ }
980
+ /**
981
+ * Removes the current scope from the logger.
982
+ *
983
+ * Clears all scope names that were set by previous scope() calls.
984
+ * After calling this, log messages will no longer include scope information.
985
+ * @example
986
+ * ```typescript
987
+ * const logger = createPail();
988
+ * const scopedLogger = logger.scope("auth");
989
+ * scopedLogger.info("Scoped message"); // Has scope
990
+ * scopedLogger.unscope();
991
+ * scopedLogger.info("Unscoped message"); // No scope
992
+ * ```
993
+ */
994
+ unscope() {
995
+ this.scopeName = [];
996
+ }
997
+ /**
998
+ * Creates a child logger that inherits settings from the parent.
999
+ *
1000
+ * Returns a new logger instance that inherits all configuration from the parent
1001
+ * (reporters, processors, types, log levels, throttle settings, etc.) while allowing
1002
+ * you to override only what you need. Child loggers are independent instances with
1003
+ * their own state (timers, counters, etc.).
1004
+ * @template N - The new custom logger type names
1005
+ * @template LC - The new log level types
1006
+ * @param options Configuration options to override or extend parent settings
1007
+ * @returns A new child logger instance
1008
+ * @example
1009
+ * ```typescript
1010
+ * const parent = createPail({
1011
+ * logLevel: "info",
1012
+ * types: { http: { label: "HTTP", logLevel: "info" } },
1013
+ * reporters: [new PrettyReporter()],
1014
+ * });
1015
+ *
1016
+ * // Child inherits parent settings but overrides log level
1017
+ * const child = parent.child({ logLevel: "debug" });
1018
+ * child.info("This will be logged"); // Uses debug level from child
1019
+ * child.http("GET /api 200"); // Inherits http type from parent
1020
+ *
1021
+ * // Child can add new types
1022
+ * const childWithNewType = parent.child({
1023
+ * types: { db: { label: "DB", logLevel: "info" } },
1024
+ * });
1025
+ * childWithNewType.db("Query executed"); // New type available
1026
+ * ```
1027
+ */
1028
+ child(options) {
1029
+ const typesChanged = options?.types !== void 0;
1030
+ const mergedTypes = typesChanged ? mergeTypes(this.types, options.types) : this.types;
1031
+ const childReporters = options?.reporters ?? [];
1032
+ const allReporters = childReporters.length > 0 ? [...this.reporters, ...childReporters] : [...this.reporters];
1033
+ const childProcessors = options?.processors ?? [];
1034
+ const allProcessors = childProcessors.length > 0 ? [...this.processors, ...childProcessors] : [...this.processors];
1035
+ const mergedLogLevels = options?.logLevels ? { ...this.logLevels, ...options.logLevels } : this.logLevels;
1036
+ let mergedScope;
1037
+ if (options?.scope) {
1038
+ const childScope = arrayify(options.scope).filter(Boolean);
1039
+ mergedScope = this.scopeName.length > 0 ? [...this.scopeName, ...childScope] : childScope;
1040
+ } else {
1041
+ mergedScope = this.scopeName.length > 0 ? this.scopeName : [];
1042
+ }
1043
+ const mergedMessages = options?.messages ? {
1044
+ timerEnd: this.endTimerMessage,
1045
+ timerStart: this.startTimerMessage,
1046
+ ...options.messages
1047
+ } : {
1048
+ timerEnd: this.endTimerMessage,
1049
+ timerStart: this.startTimerMessage
1050
+ };
1051
+ const childOptions = {
1052
+ disabled: options?.disabled ?? this.disabled,
1053
+ logLevel: options?.logLevel ?? this.generalLogLevel,
1054
+ logLevels: mergedLogLevels,
1055
+ messages: mergedMessages,
1056
+ processors: allProcessors,
1057
+ rawReporter: options?.rawReporter ?? this.rawReporter,
1058
+ reporters: allReporters,
1059
+ scope: mergedScope,
1060
+ throttle: options?.throttle ?? this.throttle,
1061
+ throttleMin: options?.throttleMin ?? this.throttleMin
1062
+ };
1063
+ if (typesChanged) {
1064
+ childOptions.parentTypes = mergedTypes;
1065
+ childOptions.parentLongestLabel = getLongestLabel(mergedTypes);
1066
+ } else {
1067
+ childOptions.parentTypes = this.types;
1068
+ childOptions.parentLongestLabel = this.longestLabel;
1069
+ }
1070
+ if (!options?.logLevels) {
1071
+ childOptions.parentLogLevels = this.logLevels;
1072
+ }
1073
+ if (!options?.messages) {
1074
+ childOptions.parentMessages = {
1075
+ timerEnd: this.endTimerMessage,
1076
+ timerStart: this.startTimerMessage
1077
+ };
1078
+ }
1079
+ childOptions.parentStringify = this.stringify;
1080
+ return new PailBrowserImpl(childOptions);
1081
+ }
1082
+ /**
1083
+ * Starts a timer with the specified label.
1084
+ *
1085
+ * Records the current timestamp and associates it with the given label.
1086
+ * Multiple timers can be active simultaneously with different labels.
1087
+ * @param label The timer label (defaults to "default")
1088
+ * @example
1089
+ * ```typescript
1090
+ * const logger = createPail();
1091
+ * logger.time("operation");
1092
+ * // ... some operation ...
1093
+ * logger.timeEnd("operation"); // Logs: "Timer run for: X ms"
1094
+ * ```
1095
+ */
1096
+ time(label = "default") {
1097
+ if (this.seqTimers.has(label)) {
1098
+ this.logger("warn", false, false, {
1099
+ message: `Timer '${label}' already exists`,
1100
+ prefix: label
1101
+ });
1102
+ } else {
1103
+ this.seqTimers.add(label);
1104
+ this.timersMap.set(label, Date.now());
1105
+ this.logger("start", false, false, {
1106
+ message: this.startTimerMessage,
1107
+ prefix: label
1108
+ });
1109
+ }
1110
+ }
1111
+ /**
1112
+ * Logs the current elapsed time for a timer without stopping it.
1113
+ *
1114
+ * Calculates and logs the time elapsed since the timer was started,
1115
+ * but keeps the timer running. If no label is provided, uses the
1116
+ * most recently started timer.
1117
+ * @param label The timer label (uses last timer if not specified)
1118
+ * @param data Additional data to include in the log message
1119
+ * @example
1120
+ * ```typescript
1121
+ * const logger = createPail();
1122
+ * logger.time("task");
1123
+ * // ... some work ...
1124
+ * logger.timeLog("task"); // Logs current elapsed time
1125
+ * // ... more work ...
1126
+ * logger.timeEnd("task"); // Logs final time and stops timer
1127
+ * ```
1128
+ */
1129
+ timeLog(label, ...data) {
1130
+ if (!label && this.seqTimers.size > 0) {
1131
+ label = [...this.seqTimers].pop();
1132
+ }
1133
+ if (label && this.timersMap.has(label)) {
1134
+ const span = Date.now() - this.timersMap.get(label);
1135
+ this.logger("info", false, false, {
1136
+ context: data,
1137
+ message: span < 1e3 ? `${String(span)} ms` : `${(span / 1e3).toFixed(2)} s`,
1138
+ prefix: label
1139
+ });
1140
+ } else {
1141
+ this.logger("warn", false, false, {
1142
+ context: data,
1143
+ message: "Timer not found",
1144
+ prefix: label
1145
+ });
1146
+ }
1147
+ }
1148
+ /**
1149
+ * Stops a timer and logs the final elapsed time.
1150
+ *
1151
+ * Calculates the total time elapsed since the timer was started,
1152
+ * logs the result, and removes the timer. If no label is provided,
1153
+ * uses the most recently started timer.
1154
+ * @param label The timer label (uses last timer if not specified)
1155
+ * @example
1156
+ * ```typescript
1157
+ * const logger = createPail();
1158
+ * logger.time("operation");
1159
+ * // ... perform operation ...
1160
+ * logger.timeEnd("operation"); // Logs: "Timer run for: X ms"
1161
+ * ```
1162
+ */
1163
+ timeEnd(label) {
1164
+ if (!label && this.seqTimers.size > 0) {
1165
+ label = [...this.seqTimers].pop();
1166
+ }
1167
+ if (label && this.timersMap.has(label)) {
1168
+ const span = Date.now() - this.timersMap.get(label);
1169
+ this.timersMap.delete(label);
1170
+ this.logger("stop", false, false, {
1171
+ message: `${this.endTimerMessage} ${span < 1e3 ? `${String(span)} ms` : `${(span / 1e3).toFixed(2)} s`}`,
1172
+ prefix: label
1173
+ });
1174
+ } else {
1175
+ this.logger("warn", false, false, {
1176
+ message: "Timer not found",
1177
+ prefix: label
1178
+ });
1179
+ }
1180
+ }
1181
+ /**
1182
+ * Starts a log group with the specified label.
1183
+ *
1184
+ * Groups related log messages together. In browser environments,
1185
+ * this uses the native console.group() functionality. In other
1186
+ * environments, it tracks group nesting internally.
1187
+ * @param label The group label (defaults to "console.group")
1188
+ * @example
1189
+ * ```typescript
1190
+ * const logger = createPail();
1191
+ * logger.group("Database Operations");
1192
+ * logger.info("Connecting to database");
1193
+ * logger.info("Running migration");
1194
+ * logger.groupEnd(); // End the group
1195
+ * ```
1196
+ */
1197
+ group(label = "console.group") {
1198
+ if (globalThis.window === void 0) {
1199
+ this.groups.push(label);
1200
+ } else {
1201
+ console.group(label);
1202
+ }
1203
+ }
1204
+ /**
1205
+ * Ends the current log group.
1206
+ *
1207
+ * Closes the most recently opened log group. In browser environments,
1208
+ * this uses the native console.groupEnd() functionality.
1209
+ * @example
1210
+ * ```typescript
1211
+ * const logger = createPail();
1212
+ * logger.group("Processing");
1213
+ * logger.info("Step 1");
1214
+ * logger.info("Step 2");
1215
+ * logger.groupEnd(); // Closes the "Processing" group
1216
+ * ```
1217
+ */
1218
+ groupEnd() {
1219
+ if (globalThis.window === void 0) {
1220
+ this.groups.pop();
1221
+ } else {
1222
+ console.groupEnd();
1223
+ }
1224
+ }
1225
+ /**
1226
+ * Increments and logs a counter with the specified label.
1227
+ *
1228
+ * Maintains an internal counter for each label and logs the current count
1229
+ * each time it's called. Useful for tracking how many times certain
1230
+ * code paths are executed.
1231
+ * @param label The counter label (defaults to "default")
1232
+ * @example
1233
+ * ```typescript
1234
+ * const logger = createPail();
1235
+ * logger.count("requests"); // Logs: "requests: 1"
1236
+ * logger.count("requests"); // Logs: "requests: 2"
1237
+ * logger.count("errors"); // Logs: "errors: 1"
1238
+ * ```
1239
+ */
1240
+ count(label = "default") {
1241
+ const current = this.countMap.get(label) ?? 0;
1242
+ this.countMap.set(label, current + 1);
1243
+ this.logger("log", false, false, {
1244
+ message: `${label}: ${String(current + 1)}`,
1245
+ prefix: label
1246
+ });
1247
+ }
1248
+ /**
1249
+ * Resets a counter to zero.
1250
+ *
1251
+ * Removes the counter with the specified label, effectively resetting
1252
+ * it to zero. If the counter doesn't exist, logs a warning.
1253
+ * @param label The counter label to reset (defaults to "default")
1254
+ * @example
1255
+ * ```typescript
1256
+ * const logger = createPail();
1257
+ * logger.count("requests"); // Logs: "requests: 1"
1258
+ * logger.countReset("requests"); // Resets counter
1259
+ * logger.count("requests"); // Logs: "requests: 1" (starts over)
1260
+ * ```
1261
+ */
1262
+ countReset(label = "default") {
1263
+ if (this.countMap.has(label)) {
1264
+ this.countMap.delete(label);
1265
+ } else {
1266
+ this.logger("warn", false, false, {
1267
+ message: `Count for ${label} does not exist`,
1268
+ prefix: label
1269
+ });
1270
+ }
1271
+ }
1272
+ /**
1273
+ * Clears the console output.
1274
+ *
1275
+ * Calls the native console.clear() method to clear all output from
1276
+ * the console. This is a convenience method that wraps the native
1277
+ * console.clear() functionality.
1278
+ * @example
1279
+ * ```typescript
1280
+ * const logger = createPail();
1281
+ * logger.info("Some message");
1282
+ * logger.clear(); // Clears the console
1283
+ * ```
1284
+ */
1285
+ // eslint-disable-next-line class-methods-use-this
1286
+ clear() {
1287
+ console.clear();
1288
+ }
1289
+ /**
1290
+ * Logs a raw message bypassing normal processing.
1291
+ *
1292
+ * Sends a message directly to the raw reporter without going through
1293
+ * the normal logging pipeline (processors, throttling, etc.). This is
1294
+ * useful for logging that needs to bypass all formatting and processing.
1295
+ * @param message The raw message to log
1296
+ * @param arguments_ Additional arguments to include
1297
+ * @example
1298
+ * ```typescript
1299
+ * const logger = createPail();
1300
+ * logger.raw("Direct message", { data: "value" });
1301
+ * ```
1302
+ */
1303
+ raw(message, ...arguments_) {
1304
+ if (this.disabled) {
1305
+ return;
1306
+ }
1307
+ this.logger("log", true, false, {
1308
+ context: arguments_,
1309
+ message
1310
+ });
1311
+ }
1312
+ extendReporter(reporter) {
1313
+ if (typeof reporter.setLoggerTypes === "function") {
1314
+ reporter.setLoggerTypes(this.types);
1315
+ }
1316
+ if (typeof reporter.setStringify === "function") {
1317
+ reporter.setStringify(this.stringify);
1318
+ }
1319
+ return reporter;
1320
+ }
1321
+ registerReporters(reporters) {
1322
+ for (let i = 0; i < reporters.length; i += 1) {
1323
+ this.reporters.add(this.extendReporter(reporters[i]));
1324
+ }
1325
+ }
1326
+ registerProcessors(processors) {
1327
+ for (let i = 0; i < processors.length; i += 1) {
1328
+ const processor = processors[i];
1329
+ if (typeof processor.setStringify === "function") {
1330
+ processor.setStringify(this.stringify);
1331
+ }
1332
+ this.processors.add(processor);
1333
+ }
1334
+ }
1335
+ #report(meta, raw) {
1336
+ if (raw) {
1337
+ this.rawReporter.log(Object.freeze(meta));
1338
+ } else {
1339
+ for (const reporter of this.reporters) {
1340
+ reporter.log(Object.freeze(meta));
1341
+ }
1342
+ }
1343
+ }
1344
+ #normalizeLogLevel(level) {
1345
+ return level && this.logLevels[level] ? level : "debug";
1346
+ }
1347
+ // eslint-disable-next-line sonarjs/cognitive-complexity
1348
+ #buildMeta(typeName, type, ...arguments_) {
1349
+ const meta = {
1350
+ badge: void 0,
1351
+ context: void 0,
1352
+ error: void 0,
1353
+ label: void 0,
1354
+ message: EMPTY_SYMBOL,
1355
+ prefix: void 0,
1356
+ repeated: void 0,
1357
+ scope: void 0,
1358
+ suffix: void 0
1359
+ };
1360
+ meta.type = {
1361
+ level: type.logLevel,
1362
+ name: typeName
1363
+ };
1364
+ meta.groups = this.groups;
1365
+ meta.scope = this.scopeName;
1366
+ meta.date = /* @__PURE__ */ new Date();
1367
+ if (arguments_.length > 0 && arguments_[0] instanceof Error) {
1368
+ meta.error = arguments_[0];
1369
+ if (arguments_.length > 1) {
1370
+ meta.context = arguments_.slice(1);
1371
+ }
1372
+ } else if (arguments_.length > 0 && typeof arguments_[0] === "object" && arguments_[0] !== null && "message" in arguments_[0]) {
1373
+ const { context, message, prefix, suffix } = arguments_[0];
1374
+ if (context) {
1375
+ meta.context = context;
1376
+ }
1377
+ if (prefix) {
1378
+ meta.prefix = prefix;
1379
+ }
1380
+ if (suffix) {
1381
+ meta.suffix = suffix;
1382
+ }
1383
+ meta.message = message;
1384
+ if (arguments_.length > 1) {
1385
+ const additionalContext = arguments_.slice(1);
1386
+ if (meta.context) {
1387
+ meta.context = Array.isArray(meta.context) ? [...meta.context, ...additionalContext] : [meta.context, ...additionalContext];
1388
+ } else {
1389
+ meta.context = additionalContext;
1390
+ }
1391
+ }
1392
+ } else if (arguments_.length > 1) {
1393
+ meta.message = arguments_[0];
1394
+ meta.context = arguments_.slice(1);
1395
+ } else if (arguments_.length === 1) {
1396
+ meta.message = arguments_[0];
1397
+ } else {
1398
+ meta.message = void 0;
1399
+ }
1400
+ if (type.logLevel === "trace") {
1401
+ meta.traceError = new Error("Trace");
1402
+ }
1403
+ if (type.badge) {
1404
+ meta.badge = type.badge;
1405
+ }
1406
+ if (type.label) {
1407
+ meta.label = type.label;
1408
+ }
1409
+ return meta;
1410
+ }
1411
+ // eslint-disable-next-line sonarjs/cognitive-complexity
1412
+ logger(type, raw, force, ...messageObject) {
1413
+ if (this.disabled) {
1414
+ return;
1415
+ }
1416
+ if (this.paused) {
1417
+ this.messageQueue.push({ messageObject, raw, type });
1418
+ return;
1419
+ }
1420
+ const typeConfig = this.types[type];
1421
+ const logLevel = this.#normalizeLogLevel(typeConfig.logLevel);
1422
+ if (force || this.logLevels[logLevel] >= this.logLevels[this.generalLogLevel]) {
1423
+ let meta = this.#buildMeta(type, typeConfig, ...messageObject);
1424
+ const resolveLog = (newLog = false) => {
1425
+ const repeated = (this.lastLog.count ?? 0) - this.throttleMin;
1426
+ if (this.lastLog.object && repeated > 0) {
1427
+ const lastMeta = { ...this.lastLog.object };
1428
+ if (repeated > 1) {
1429
+ lastMeta.repeated = repeated;
1430
+ }
1431
+ this.#report(lastMeta, raw);
1432
+ this.lastLog.count = 1;
1433
+ }
1434
+ if (newLog) {
1435
+ for (const processor of this.processors) {
1436
+ meta = { ...processor.process(meta) };
1437
+ }
1438
+ this.lastLog.object = meta;
1439
+ this.#report(meta, raw);
1440
+ }
1441
+ };
1442
+ clearTimeout(this.lastLog.timeout);
1443
+ const diffTime = this.lastLog.time && meta.date ? new Date(meta.date).getTime() - this.lastLog.time.getTime() : 0;
1444
+ this.lastLog.time = new Date(meta.date);
1445
+ if (diffTime < this.throttle) {
1446
+ try {
1447
+ const isSameLog = this.lastLog.object && JSON.stringify([meta.label, meta.scope, meta.type, meta.message, meta.prefix, meta.suffix, meta.context]) === JSON.stringify([
1448
+ this.lastLog.object.label,
1449
+ this.lastLog.object.scope,
1450
+ this.lastLog.object.type,
1451
+ this.lastLog.object.message,
1452
+ this.lastLog.object.prefix,
1453
+ this.lastLog.object.suffix,
1454
+ this.lastLog.object.context
1455
+ ]);
1456
+ if (isSameLog) {
1457
+ this.lastLog.count = (this.lastLog.count ?? 0) + 1;
1458
+ if (this.lastLog.count > this.throttleMin) {
1459
+ this.lastLog.timeout = setTimeout(resolveLog, this.throttle);
1460
+ return;
1461
+ }
1462
+ }
1463
+ } catch {
1464
+ }
1465
+ }
1466
+ resolveLog(true);
1467
+ }
1468
+ }
1469
+ }
24
1470
 
25
1471
  class RawReporter {
26
1472
  #stdout;
@@ -58,7 +1504,7 @@ class RawReporter {
58
1504
  if (typeof value === "object") {
59
1505
  return ` ${inspect(value, this.#inspectOptions)}`;
60
1506
  }
61
- return ` ${value}`;
1507
+ return ` ${String(value)}`;
62
1508
  })
63
1509
  );
64
1510
  }
@@ -134,6 +1580,7 @@ class PailServerImpl extends PailBrowserImpl {
134
1580
  this.registerProcessors(processors);
135
1581
  }
136
1582
  }
1583
+ options;
137
1584
  stdout;
138
1585
  stderr;
139
1586
  interactiveManager;
@@ -179,7 +1626,7 @@ class PailServerImpl extends PailBrowserImpl {
179
1626
  */
180
1627
  // @ts-expect-error - override signature differs due to server-specific options
181
1628
  child(options) {
182
- const typesChanged = options?.types !== void 0 && options.types !== null;
1629
+ const typesChanged = options?.types !== void 0;
183
1630
  const mergedTypes = typesChanged ? mergeTypes(this.types, options.types) : this.types;
184
1631
  const childReporters = options?.reporters ?? [];
185
1632
  const allReporters = childReporters.length > 0 ? [...this.reporters, ...childReporters] : [...this.reporters];
@@ -350,99 +1797,6 @@ class PailServerImpl extends PailBrowserImpl {
350
1797
  this.restoreConsole();
351
1798
  this.restoreStd();
352
1799
  }
353
- /**
354
- * Creates a single progress bar.
355
- * @param options Configuration options for the progress bar
356
- * @returns A new ProgressBar instance
357
- * @example
358
- * ```typescript
359
- * const logger = createPail({ interactive: true });
360
- * const bar = logger.createProgressBar({
361
- * total: 100,
362
- * format: 'Downloading [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}'
363
- * });
364
- *
365
- * bar.start();
366
- * // ... do work and update progress
367
- * bar.update(50);
368
- * bar.stop();
369
- * ```
370
- */
371
- createProgressBar(options) {
372
- if (!this.interactiveManager) {
373
- throw new Error("Interactive mode is not enabled. Create Pail with { interactive: true } to use progress bars.");
374
- }
375
- const styledOptions = applyStyleToOptions(options);
376
- return new ProgressBar(styledOptions, this.interactiveManager);
377
- }
378
- /**
379
- * Creates a multi-bar progress manager for displaying multiple progress bars.
380
- * @param options Configuration options for the multi-bar manager
381
- * @returns A new MultiProgressBar instance
382
- * @example
383
- * ```typescript
384
- * const logger = createPail({ interactive: true });
385
- * const multiBar = logger.createMultiProgressBar();
386
- *
387
- * const bar1 = multiBar.create(100);
388
- * const bar2 = multiBar.create(200);
389
- *
390
- * bar1.start();
391
- * bar2.start();
392
- * // ... update bars as needed
393
- * multiBar.stop();
394
- * ```
395
- */
396
- createMultiProgressBar(options = {}) {
397
- if (!this.interactiveManager) {
398
- throw new Error("Interactive mode is not enabled. Create Pail with { interactive: true } to use progress bars.");
399
- }
400
- const styledOptions = applyStyleToOptions(options);
401
- return new MultiProgressBar(styledOptions, this.interactiveManager);
402
- }
403
- /**
404
- * Creates a single spinner.
405
- * @param options Configuration options for the spinner
406
- * @returns A new Spinner instance
407
- * @example
408
- * ```typescript
409
- * const logger = createPail({ interactive: true });
410
- * const spinner = logger.createSpinner({ name: 'dots' });
411
- * spinner.start('Loading...');
412
- * // ... do work
413
- * spinner.succeed('Done');
414
- * ```
415
- */
416
- createSpinner(options = {}) {
417
- if (!this.interactiveManager) {
418
- throw new Error("Interactive mode is not enabled. Create Pail with { interactive: true } to use spinners.");
419
- }
420
- return new Spinner(options, this.interactiveManager);
421
- }
422
- /**
423
- * Creates a multi-spinner manager for displaying multiple spinners.
424
- * @param options Configuration options for the multi-spinner manager
425
- * @returns A new MultiSpinner instance
426
- * @example
427
- * ```typescript
428
- * const logger = createPail({ interactive: true });
429
- * const multiSpinner = logger.createMultiSpinner();
430
- *
431
- * const spinner1 = multiSpinner.create('Loading 1');
432
- * const spinner2 = multiSpinner.create('Loading 2');
433
- *
434
- * spinner1.start();
435
- * spinner2.start();
436
- * // ... update spinners as needed
437
- * multiSpinner.stop();
438
- * ```
439
- */
440
- createMultiSpinner(options = {}) {
441
- if (!this.interactiveManager) {
442
- throw new Error("Interactive mode is not enabled. Create Pail with { interactive: true } to use spinners.");
443
- }
444
- return new MultiSpinner(options, this.interactiveManager);
445
- }
446
1800
  /**
447
1801
  * Clears the terminal screen.
448
1802
  *
@@ -457,8 +1811,8 @@ class PailServerImpl extends PailBrowserImpl {
457
1811
  * ```
458
1812
  */
459
1813
  clear() {
460
- this.stdout.write(clearTerminal);
461
- this.stderr.write(clearTerminal);
1814
+ this.stdout.write(resetTerminal);
1815
+ this.stderr.write(resetTerminal);
462
1816
  }
463
1817
  extendReporter(reporter) {
464
1818
  if (typeof reporter.setStdout === "function") {
@@ -505,6 +1859,922 @@ class PailServerImpl extends PailBrowserImpl {
505
1859
  }
506
1860
  const PailServer = PailServerImpl;
507
1861
 
1862
+ const colorKeywords = /* @__PURE__ */ new Map([
1863
+ ["aliceblue", "#f0f8ff"],
1864
+ ["antiquewhite", "#faebd7"],
1865
+ ["aqua", "#00ffff"],
1866
+ ["aquamarine", "#7fffd4"],
1867
+ ["azure", "#f0ffff"],
1868
+ ["beige", "#f5f5dc"],
1869
+ ["bisque", "#ffe4c4"],
1870
+ ["black", "#000000"],
1871
+ ["blanchedalmond", "#ffebcd"],
1872
+ ["blue", "#0000ff"],
1873
+ ["blueviolet", "#8a2be2"],
1874
+ ["brown", "#a52a2a"],
1875
+ ["burlywood", "#deb887"],
1876
+ ["cadetblue", "#5f9ea0"],
1877
+ ["chartreuse", "#7fff00"],
1878
+ ["chocolate", "#d2691e"],
1879
+ ["coral", "#ff7f50"],
1880
+ ["cornflowerblue", "#6495ed"],
1881
+ ["cornsilk", "#fff8dc"],
1882
+ ["crimson", "#dc143c"],
1883
+ ["cyan", "#00ffff"],
1884
+ ["darkblue", "#00008b"],
1885
+ ["darkcyan", "#008b8b"],
1886
+ ["darkgoldenrod", "#b8860b"],
1887
+ ["darkgray", "#a9a9a9"],
1888
+ ["darkgreen", "#006400"],
1889
+ ["darkgrey", "#a9a9a9"],
1890
+ ["darkkhaki", "#bdb76b"],
1891
+ ["darkmagenta", "#8b008b"],
1892
+ ["darkolivegreen", "#556b2f"],
1893
+ ["darkorange", "#ff8c00"],
1894
+ ["darkorchid", "#9932cc"],
1895
+ ["darkred", "#8b0000"],
1896
+ ["darksalmon", "#e9967a"],
1897
+ ["darkseagreen", "#8fbc8f"],
1898
+ ["darkslateblue", "#483d8b"],
1899
+ ["darkslategray", "#2f4f4f"],
1900
+ ["darkslategrey", "#2f4f4f"],
1901
+ ["darkturquoise", "#00ced1"],
1902
+ ["darkviolet", "#9400d3"],
1903
+ ["deeppink", "#ff1493"],
1904
+ ["deepskyblue", "#00bfff"],
1905
+ ["dimgray", "#696969"],
1906
+ ["dimgrey", "#696969"],
1907
+ ["dodgerblue", "#1e90ff"],
1908
+ ["firebrick", "#b22222"],
1909
+ ["floralwhite", "#fffaf0"],
1910
+ ["forestgreen", "#228b22"],
1911
+ ["fuchsia", "#ff00ff"],
1912
+ ["gainsboro", "#dcdcdc"],
1913
+ ["ghostwhite", "#f8f8ff"],
1914
+ ["gold", "#ffd700"],
1915
+ ["goldenrod", "#daa520"],
1916
+ ["gray", "#808080"],
1917
+ ["green", "#008000"],
1918
+ ["greenyellow", "#adff2f"],
1919
+ ["grey", "#808080"],
1920
+ ["honeydew", "#f0fff0"],
1921
+ ["hotpink", "#ff69b4"],
1922
+ ["indianred", "#cd5c5c"],
1923
+ ["indigo", "#4b0082"],
1924
+ ["ivory", "#fffff0"],
1925
+ ["khaki", "#f0e68c"],
1926
+ ["lavender", "#e6e6fa"],
1927
+ ["lavenderblush", "#fff0f5"],
1928
+ ["lawngreen", "#7cfc00"],
1929
+ ["lemonchiffon", "#fffacd"],
1930
+ ["lightblue", "#add8e6"],
1931
+ ["lightcoral", "#f08080"],
1932
+ ["lightcyan", "#e0ffff"],
1933
+ ["lightgoldenrodyellow", "#fafad2"],
1934
+ ["lightgray", "#d3d3d3"],
1935
+ ["lightgreen", "#90ee90"],
1936
+ ["lightgrey", "#d3d3d3"],
1937
+ ["lightpink", "#ffb6c1"],
1938
+ ["lightsalmon", "#ffa07a"],
1939
+ ["lightseagreen", "#20b2aa"],
1940
+ ["lightskyblue", "#87cefa"],
1941
+ ["lightslategray", "#778899"],
1942
+ ["lightslategrey", "#778899"],
1943
+ ["lightsteelblue", "#b0c4de"],
1944
+ ["lightyellow", "#ffffe0"],
1945
+ ["lime", "#00ff00"],
1946
+ ["limegreen", "#32cd32"],
1947
+ ["linen", "#faf0e6"],
1948
+ ["magenta", "#ff00ff"],
1949
+ ["maroon", "#800000"],
1950
+ ["mediumaquamarine", "#66cdaa"],
1951
+ ["mediumblue", "#0000cd"],
1952
+ ["mediumorchid", "#ba55d3"],
1953
+ ["mediumpurple", "#9370db"],
1954
+ ["mediumseagreen", "#3cb371"],
1955
+ ["mediumslateblue", "#7b68ee"],
1956
+ ["mediumspringgreen", "#00fa9a"],
1957
+ ["mediumturquoise", "#48d1cc"],
1958
+ ["mediumvioletred", "#c71585"],
1959
+ ["midnightblue", "#191970"],
1960
+ ["mintcream", "#f5fffa"],
1961
+ ["mistyrose", "#ffe4e1"],
1962
+ ["moccasin", "#ffe4b5"],
1963
+ ["navajowhite", "#ffdead"],
1964
+ ["navy", "#000080"],
1965
+ ["oldlace", "#fdf5e6"],
1966
+ ["olive", "#808000"],
1967
+ ["olivedrab", "#6b8e23"],
1968
+ ["orange", "#ffa500"],
1969
+ ["orangered", "#ff4500"],
1970
+ ["orchid", "#da70d6"],
1971
+ ["palegoldenrod", "#eee8aa"],
1972
+ ["palegreen", "#98fb98"],
1973
+ ["paleturquoise", "#afeeee"],
1974
+ ["palevioletred", "#db7093"],
1975
+ ["papayawhip", "#ffefd5"],
1976
+ ["peachpuff", "#ffdab9"],
1977
+ ["peru", "#cd853f"],
1978
+ ["pink", "#ffc0cb"],
1979
+ ["plum", "#dda0dd"],
1980
+ ["powderblue", "#b0e0e6"],
1981
+ ["purple", "#800080"],
1982
+ ["rebeccapurple", "#663399"],
1983
+ ["red", "#ff0000"],
1984
+ ["rosybrown", "#bc8f8f"],
1985
+ ["royalblue", "#4169e1"],
1986
+ ["saddlebrown", "#8b4513"],
1987
+ ["salmon", "#fa8072"],
1988
+ ["sandybrown", "#f4a460"],
1989
+ ["seagreen", "#2e8b57"],
1990
+ ["seashell", "#fff5ee"],
1991
+ ["sienna", "#a0522d"],
1992
+ ["silver", "#c0c0c0"],
1993
+ ["skyblue", "#87ceeb"],
1994
+ ["slateblue", "#6a5acd"],
1995
+ ["slategray", "#708090"],
1996
+ ["slategrey", "#708090"],
1997
+ ["snow", "#fffafa"],
1998
+ ["springgreen", "#00ff7f"],
1999
+ ["steelblue", "#4682b4"],
2000
+ ["tan", "#d2b48c"],
2001
+ ["teal", "#008080"],
2002
+ ["thistle", "#d8bfd8"],
2003
+ ["tomato", "#ff6347"],
2004
+ ["turquoise", "#40e0d0"],
2005
+ ["violet", "#ee82ee"],
2006
+ ["wheat", "#f5deb3"],
2007
+ ["white", "#ffffff"],
2008
+ ["whitesmoke", "#f5f5f5"],
2009
+ ["yellow", "#ffff00"],
2010
+ ["yellowgreen", "#9acd32"]
2011
+ ]);
2012
+ const HASH_PATTERN = /^#([\dA-F]{2})([\dA-F]{2})([\dA-F]{2})([\dA-F]{2})?$/i;
2013
+ const SMALL_HASH_PATTERN = /^#([\dA-F])([\dA-F])([\dA-F])([\dA-F])?$/i;
2014
+ const RGB_PATTERN = /^rgba?\(\s*([+-]?(?:\d+(?:\.\d+)?|\.\d+))\s*,\s*([+-]?(?:\d+(?:\.\d+)?|\.\d+))\s*,\s*([+-]?(?:\d+(?:\.\d+)?|\.\d+))\s*(,\s*([+-]?(?:\d+(?:\.\d+)?|\.\d+))\s*)?\)$/;
2015
+ const HSL_PATTERN = /^hsla?\(\s*([+-]?(?:\d+(?:\.\d+)?|\.\d+))\s*,\s*([+-]?(?:\d+(?:\.\d+)?|\.\d+))%\s*,\s*([+-]?(?:\d+(?:\.\d+)?|\.\d+))%\s*(,\s*([+-]?(?:\d+(?:\.\d+)?|\.\d+))\s*)?\)$/;
2016
+ const getDefaultCss = () => {
2017
+ return {
2018
+ __proto__: null,
2019
+ backgroundColor: null,
2020
+ color: null,
2021
+ fontStyle: null,
2022
+ fontWeight: null,
2023
+ textDecorationColor: null,
2024
+ textDecorationLine: []
2025
+ };
2026
+ };
2027
+ const SPACE_PATTERN = /\s+/;
2028
+ const parseCssColor = (colorString) => {
2029
+ if (colorKeywords.has(colorString)) {
2030
+ colorString = colorKeywords.get(colorString);
2031
+ }
2032
+ const hashMatch = HASH_PATTERN.exec(colorString);
2033
+ if (hashMatch) {
2034
+ return [Number.parseInt(hashMatch[1], 16), Number.parseInt(hashMatch[2], 16), Number.parseInt(hashMatch[3], 16)];
2035
+ }
2036
+ const smallHashMatch = SMALL_HASH_PATTERN.exec(colorString);
2037
+ if (smallHashMatch) {
2038
+ return [
2039
+ Number.parseInt(`${smallHashMatch[1]}${smallHashMatch[1]}`, 16),
2040
+ Number.parseInt(`${smallHashMatch[2]}${smallHashMatch[2]}`, 16),
2041
+ Number.parseInt(`${smallHashMatch[3]}${smallHashMatch[3]}`, 16)
2042
+ ];
2043
+ }
2044
+ const rgbMatch = RGB_PATTERN.exec(colorString);
2045
+ if (rgbMatch) {
2046
+ return [
2047
+ Math.round(Math.max(0, Math.min(255, Number(rgbMatch[1])))),
2048
+ Math.round(Math.max(0, Math.min(255, Number(rgbMatch[2])))),
2049
+ Math.round(Math.max(0, Math.min(255, Number(rgbMatch[3]))))
2050
+ ];
2051
+ }
2052
+ const hslMatch = HSL_PATTERN.exec(colorString);
2053
+ if (hslMatch) {
2054
+ let h = Number(hslMatch[1]) % 360;
2055
+ if (h < 0) {
2056
+ h += 360;
2057
+ }
2058
+ const s = Math.max(0, Math.min(100, Number(hslMatch[2]))) / 100;
2059
+ const l = Math.max(0, Math.min(100, Number(hslMatch[3]))) / 100;
2060
+ const c = (1 - Math.abs(2 * l - 1)) * s;
2061
+ const x = c * (1 - Math.abs(h / 60 % 2 - 1));
2062
+ const m = l - c / 2;
2063
+ let r_;
2064
+ let g_;
2065
+ let b_;
2066
+ if (h < 60) {
2067
+ ({ 0: r_, 1: g_, 2: b_ } = [c, x, 0]);
2068
+ } else if (h < 120) {
2069
+ ({ 0: r_, 1: g_, 2: b_ } = [x, c, 0]);
2070
+ } else if (h < 180) {
2071
+ ({ 0: r_, 1: g_, 2: b_ } = [0, c, x]);
2072
+ } else if (h < 240) {
2073
+ ({ 0: r_, 1: g_, 2: b_ } = [0, x, c]);
2074
+ } else if (h < 300) {
2075
+ ({ 0: r_, 1: g_, 2: b_ } = [x, 0, c]);
2076
+ } else {
2077
+ ({ 0: r_, 1: g_, 2: b_ } = [c, 0, x]);
2078
+ }
2079
+ return [Math.round((r_ + m) * 255), Math.round((g_ + m) * 255), Math.round((b_ + m) * 255)];
2080
+ }
2081
+ return null;
2082
+ };
2083
+ const colorEquals = (color1, color2) => color1?.[0] === color2?.[0] && color1?.[1] === color2?.[1] && color1?.[2] === color2?.[2];
2084
+ const parseCss = (cssString) => {
2085
+ const css = getDefaultCss();
2086
+ const rawEntries = [];
2087
+ let inValue = false;
2088
+ let currentKey = null;
2089
+ let parenthesesDepth = 0;
2090
+ let currentPart = "";
2091
+ for (const c of cssString) {
2092
+ if (c === "(") {
2093
+ parenthesesDepth += 1;
2094
+ } else if (parenthesesDepth > 0) {
2095
+ if (c === ")") {
2096
+ parenthesesDepth -= 1;
2097
+ }
2098
+ } else if (inValue) {
2099
+ if (c === ";") {
2100
+ const value = currentPart.trim();
2101
+ if (value !== "") {
2102
+ rawEntries.push([currentKey, value]);
2103
+ }
2104
+ currentKey = null;
2105
+ currentPart = "";
2106
+ inValue = false;
2107
+ continue;
2108
+ }
2109
+ } else if (c === ":") {
2110
+ currentKey = currentPart.trim();
2111
+ currentPart = "";
2112
+ inValue = true;
2113
+ continue;
2114
+ }
2115
+ currentPart += c;
2116
+ }
2117
+ if (inValue && parenthesesDepth === 0) {
2118
+ const value = currentPart.trim();
2119
+ if (value !== "") {
2120
+ rawEntries.push([currentKey, value]);
2121
+ }
2122
+ currentKey = null;
2123
+ currentPart = "";
2124
+ }
2125
+ for (const { 0: key, 1: value } of rawEntries) {
2126
+ switch (key) {
2127
+ case "background-color": {
2128
+ if (value != void 0) {
2129
+ css.backgroundColor = value;
2130
+ }
2131
+ break;
2132
+ }
2133
+ case "color": {
2134
+ if (value != void 0) {
2135
+ css.color = value;
2136
+ }
2137
+ break;
2138
+ }
2139
+ case "font-style": {
2140
+ if (["italic", "oblique", "oblique 14deg"].includes(value)) {
2141
+ css.fontStyle = "italic";
2142
+ }
2143
+ break;
2144
+ }
2145
+ case "font-weight": {
2146
+ if (value === "bold") {
2147
+ css.fontWeight = value;
2148
+ }
2149
+ break;
2150
+ }
2151
+ case "text-decoration": {
2152
+ css.textDecorationColor = null;
2153
+ css.textDecorationLine = [];
2154
+ const arguments_ = value.split(SPACE_PATTERN);
2155
+ for (const argument of arguments_) {
2156
+ const maybeColor = parseCssColor(argument);
2157
+ if (maybeColor != void 0) {
2158
+ css.textDecorationColor = maybeColor;
2159
+ } else if (["line-through", "overline", "underline"].includes(argument)) {
2160
+ css.textDecorationLine.push(argument);
2161
+ }
2162
+ }
2163
+ break;
2164
+ }
2165
+ case "text-decoration-color": {
2166
+ const color = parseCssColor(value);
2167
+ if (color != void 0) {
2168
+ css.textDecorationColor = color;
2169
+ }
2170
+ break;
2171
+ }
2172
+ case "text-decoration-line": {
2173
+ css.textDecorationLine = [];
2174
+ const lineTypes = value.split(SPACE_PATTERN);
2175
+ for (const lineType of lineTypes) {
2176
+ if (["line-through", "overline", "underline"].includes(lineType)) {
2177
+ css.textDecorationLine.push(lineType);
2178
+ }
2179
+ }
2180
+ break;
2181
+ }
2182
+ }
2183
+ }
2184
+ return css;
2185
+ };
2186
+ const cssToAnsi = (css, previousCss = null) => {
2187
+ previousCss = previousCss ?? getDefaultCss();
2188
+ let ansi = "";
2189
+ if (!colorEquals(css.backgroundColor, previousCss.backgroundColor)) {
2190
+ if (css.backgroundColor == void 0) {
2191
+ ansi += "\x1B[49m";
2192
+ } else {
2193
+ switch (css.backgroundColor) {
2194
+ case "black": {
2195
+ ansi += "\x1B[40m";
2196
+ break;
2197
+ }
2198
+ case "blue": {
2199
+ ansi += "\x1B[44m";
2200
+ break;
2201
+ }
2202
+ case "cyan": {
2203
+ ansi += "\x1B[46m";
2204
+ break;
2205
+ }
2206
+ case "green": {
2207
+ ansi += "\x1B[42m";
2208
+ break;
2209
+ }
2210
+ case "magenta": {
2211
+ ansi += "\x1B[45m";
2212
+ break;
2213
+ }
2214
+ case "red": {
2215
+ ansi += "\x1B[41m";
2216
+ break;
2217
+ }
2218
+ case "white": {
2219
+ ansi += "\x1B[47m";
2220
+ break;
2221
+ }
2222
+ case "yellow": {
2223
+ ansi += "\x1B[43m";
2224
+ break;
2225
+ }
2226
+ default: {
2227
+ if (Array.isArray(css.backgroundColor)) {
2228
+ const { 0: r, 1: g, 2: b } = css.backgroundColor;
2229
+ ansi += `\x1B[48;2;${String(r)};${String(g)};${String(b)}m`;
2230
+ } else {
2231
+ const parsed = parseCssColor(css.backgroundColor);
2232
+ if (parsed === null) {
2233
+ ansi += "\x1B[49m";
2234
+ } else {
2235
+ const { 0: r, 1: g, 2: b } = parsed;
2236
+ ansi += `\x1B[48;2;${String(r)};${String(g)};${String(b)}m`;
2237
+ }
2238
+ }
2239
+ }
2240
+ }
2241
+ }
2242
+ }
2243
+ if (!colorEquals(css.color, previousCss.color)) {
2244
+ if (css.color == void 0) {
2245
+ ansi += "\x1B[39m";
2246
+ } else {
2247
+ switch (css.color) {
2248
+ case "black": {
2249
+ ansi += "\x1B[30m";
2250
+ break;
2251
+ }
2252
+ case "blue": {
2253
+ ansi += "\x1B[34m";
2254
+ break;
2255
+ }
2256
+ case "cyan": {
2257
+ ansi += "\x1B[36m";
2258
+ break;
2259
+ }
2260
+ case "green": {
2261
+ ansi += "\x1B[32m";
2262
+ break;
2263
+ }
2264
+ case "magenta": {
2265
+ ansi += "\x1B[35m";
2266
+ break;
2267
+ }
2268
+ case "red": {
2269
+ ansi += "\x1B[31m";
2270
+ break;
2271
+ }
2272
+ case "white": {
2273
+ ansi += "\x1B[37m";
2274
+ break;
2275
+ }
2276
+ case "yellow": {
2277
+ ansi += "\x1B[33m";
2278
+ break;
2279
+ }
2280
+ default: {
2281
+ if (Array.isArray(css.color)) {
2282
+ const { 0: r, 1: g, 2: b } = css.color;
2283
+ ansi += `\x1B[38;2;${String(r)};${String(g)};${String(b)}m`;
2284
+ } else {
2285
+ const parsed = parseCssColor(css.color);
2286
+ if (parsed === null) {
2287
+ ansi += "\x1B[39m";
2288
+ } else {
2289
+ const { 0: r, 1: g, 2: b } = parsed;
2290
+ ansi += `\x1B[38;2;${String(r)};${String(g)};${String(b)}m`;
2291
+ }
2292
+ }
2293
+ }
2294
+ }
2295
+ }
2296
+ }
2297
+ if (css.fontWeight !== previousCss.fontWeight) {
2298
+ ansi += css.fontWeight === "bold" ? "\x1B[1m" : "\x1B[22m";
2299
+ }
2300
+ if (css.fontStyle !== previousCss.fontStyle) {
2301
+ ansi += css.fontStyle === "italic" ? "\x1B[3m" : "\x1B[23m";
2302
+ }
2303
+ if (!colorEquals(css.textDecorationColor, previousCss.textDecorationColor)) {
2304
+ if (css.textDecorationColor == void 0) {
2305
+ ansi += "\x1B[59m";
2306
+ } else {
2307
+ const { 0: r, 1: g, 2: b } = css.textDecorationColor;
2308
+ ansi += `\x1B[58;2;${String(r)};${String(g)};${String(b)}m`;
2309
+ }
2310
+ }
2311
+ if (css.textDecorationLine.includes("line-through") !== previousCss.textDecorationLine.includes("line-through")) {
2312
+ ansi += css.textDecorationLine.includes("line-through") ? "\x1B[9m" : "\x1B[29m";
2313
+ }
2314
+ if (css.textDecorationLine.includes("overline") !== previousCss.textDecorationLine.includes("overline")) {
2315
+ ansi += css.textDecorationLine.includes("overline") ? "\x1B[53m" : "\x1B[55m";
2316
+ }
2317
+ if (css.textDecorationLine.includes("underline") !== previousCss.textDecorationLine.includes("underline")) {
2318
+ ansi += css.textDecorationLine.includes("underline") ? "\x1B[4m" : "\x1B[24m";
2319
+ }
2320
+ return ansi;
2321
+ };
2322
+ const tryStringify = (o) => {
2323
+ try {
2324
+ return JSON.stringify(o);
2325
+ } catch {
2326
+ return '"[Circular]"';
2327
+ }
2328
+ };
2329
+ const CHAR_PERCENT = "%".codePointAt(0);
2330
+ const CHAR_s = "s".codePointAt(0);
2331
+ const CHAR_d = "d".codePointAt(0);
2332
+ const CHAR_f = "f".codePointAt(0);
2333
+ const CHAR_i = "i".codePointAt(0);
2334
+ const CHAR_O = "O".codePointAt(0);
2335
+ const CHAR_o = "o".codePointAt(0);
2336
+ const CHAR_j = "j".codePointAt(0);
2337
+ const CHAR_c = "c".codePointAt(0);
2338
+ const format = (fmt, arguments_ = [], options = {}) => {
2339
+ if (typeof fmt !== "string" && typeof fmt !== "object" || fmt === null) {
2340
+ throw new TypeError(`fmt must be a string or object, got ${fmt === null ? "null" : typeof fmt}`);
2341
+ }
2342
+ const stringify = options.stringify ?? tryStringify;
2343
+ const offset = 1;
2344
+ if (typeof fmt === "object") {
2345
+ const argumentsLength = arguments_.length + offset;
2346
+ if (argumentsLength === 1) {
2347
+ return "{}";
2348
+ }
2349
+ const objects = Array.from({ length: argumentsLength });
2350
+ objects[0] = stringify(fmt);
2351
+ for (let index = 1; index < argumentsLength; index += 1) {
2352
+ objects[index] = stringify(arguments_[index - offset]);
2353
+ }
2354
+ return objects.join(" ");
2355
+ }
2356
+ if (arguments_.length === 0) {
2357
+ return fmt;
2358
+ }
2359
+ let result = "";
2360
+ let a = 1 - offset;
2361
+ let lastPosition = -1;
2362
+ let usedStyle = false;
2363
+ let previousCss = null;
2364
+ for (let index = 0; index < fmt.length; ) {
2365
+ if (fmt.codePointAt(index) === CHAR_PERCENT && index + 1 < fmt.length) {
2366
+ lastPosition = lastPosition > -1 ? lastPosition : 0;
2367
+ const c = fmt.codePointAt(index + 1);
2368
+ if (c === void 0) {
2369
+ a += 1;
2370
+ break;
2371
+ }
2372
+ switch (c) {
2373
+ case CHAR_c: {
2374
+ if (globalThis.window === void 0) {
2375
+ const css = parseCss(arguments_[a]);
2376
+ if (lastPosition < index) {
2377
+ result += fmt.slice(lastPosition, index);
2378
+ }
2379
+ result += cssToAnsi(css, previousCss);
2380
+ if (result !== "") {
2381
+ usedStyle = true;
2382
+ previousCss = css;
2383
+ }
2384
+ }
2385
+ lastPosition = index + 2;
2386
+ index += 1;
2387
+ break;
2388
+ }
2389
+ case CHAR_d:
2390
+ case CHAR_f: {
2391
+ if (a >= arguments_.length || arguments_[a] == void 0) {
2392
+ break;
2393
+ }
2394
+ if (lastPosition < index) {
2395
+ result += fmt.slice(lastPosition, index);
2396
+ }
2397
+ result += Number(arguments_[a]).toString();
2398
+ lastPosition = index + 2;
2399
+ index += 1;
2400
+ break;
2401
+ }
2402
+ case CHAR_i: {
2403
+ if (a >= arguments_.length || arguments_[a] == void 0) {
2404
+ break;
2405
+ }
2406
+ if (lastPosition < index) {
2407
+ result += fmt.slice(lastPosition, index);
2408
+ }
2409
+ result += Math.floor(Number(arguments_[a])).toString();
2410
+ lastPosition = index + 2;
2411
+ index += 1;
2412
+ break;
2413
+ }
2414
+ case CHAR_j:
2415
+ case CHAR_O:
2416
+ case CHAR_o: {
2417
+ if (a >= arguments_.length || arguments_[a] === void 0) {
2418
+ break;
2419
+ }
2420
+ if (lastPosition < index) {
2421
+ result += fmt.slice(lastPosition, index);
2422
+ }
2423
+ const temporaryArgument = arguments_[a];
2424
+ const type = typeof temporaryArgument;
2425
+ if (type === "string") {
2426
+ result += `'${temporaryArgument}'`;
2427
+ lastPosition = index + 2;
2428
+ break;
2429
+ }
2430
+ if (type === "function") {
2431
+ result += temporaryArgument.name ? `[Function: ${temporaryArgument.name}]` : "[Function: <anonymous>]";
2432
+ lastPosition = index + 2;
2433
+ break;
2434
+ }
2435
+ result += stringify(temporaryArgument);
2436
+ lastPosition = index + 2;
2437
+ index += 1;
2438
+ break;
2439
+ }
2440
+ case CHAR_PERCENT: {
2441
+ if (lastPosition < index) {
2442
+ result += fmt.slice(lastPosition, index);
2443
+ }
2444
+ result += "%";
2445
+ lastPosition = index + 2;
2446
+ index += 1;
2447
+ a -= 1;
2448
+ break;
2449
+ }
2450
+ case CHAR_s: {
2451
+ if (a >= arguments_.length) {
2452
+ break;
2453
+ }
2454
+ if (lastPosition < index) {
2455
+ result += fmt.slice(lastPosition, index);
2456
+ }
2457
+ result += typeof arguments_[a] === "object" ? stringify(arguments_[a]) : String(arguments_[a]);
2458
+ lastPosition = index + 2;
2459
+ index += 1;
2460
+ break;
2461
+ }
2462
+ default: {
2463
+ if (typeof options.formatters?.[c] === "function") {
2464
+ if (lastPosition < index) {
2465
+ result += fmt.slice(lastPosition, index);
2466
+ }
2467
+ result += options.formatters[c](arguments_[a]);
2468
+ lastPosition = index + 2;
2469
+ index += 1;
2470
+ }
2471
+ }
2472
+ }
2473
+ a += 1;
2474
+ }
2475
+ index += 1;
2476
+ }
2477
+ if (lastPosition === -1) {
2478
+ return fmt;
2479
+ }
2480
+ if (lastPosition < fmt.length) {
2481
+ result += fmt.slice(lastPosition);
2482
+ }
2483
+ if (usedStyle) {
2484
+ result += "\x1B[0m";
2485
+ }
2486
+ return result;
2487
+ };
2488
+ const build = (options = {}) => {
2489
+ const formatters = {};
2490
+ if (typeof options.formatters === "object") {
2491
+ Object.entries(options.formatters).forEach(([key, formatterFunction]) => {
2492
+ if (key.length === 0) {
2493
+ throw new Error(`Formatter %${key} has no characters`);
2494
+ }
2495
+ if (key.length > 1) {
2496
+ throw new Error(`Formatter %${key} has more than one character`);
2497
+ }
2498
+ if (typeof formatterFunction !== "function") {
2499
+ throw new TypeError(`Formatter for %${key} is not a function`);
2500
+ }
2501
+ const c = key.codePointAt(0);
2502
+ if (c === void 0) {
2503
+ throw new Error(`${key}.codePointAt(0) failed to return a value, please report this issue`);
2504
+ }
2505
+ formatters[c] = formatterFunction;
2506
+ });
2507
+ }
2508
+ return (f, arguments_ = [], formatOptions = {}) => format(f, arguments_, { ...formatOptions, formatters });
2509
+ };
2510
+
2511
+ class MessageFormatterProcessor {
2512
+ /** Custom stringify function for object serialization */
2513
+ #stringify;
2514
+ /** Custom formatters for message interpolation */
2515
+ #formatters;
2516
+ /**
2517
+ * Creates a new MessageFormatterProcessor instance.
2518
+ * @param options Configuration options
2519
+ * @param options.formatters Custom formatters for message interpolation
2520
+ */
2521
+ constructor(options = {}) {
2522
+ this.#formatters = options.formatters;
2523
+ }
2524
+ /**
2525
+ * Sets the stringify function for object serialization.
2526
+ * @param function_ The stringify function to use for serializing objects
2527
+ */
2528
+ setStringify(function_) {
2529
+ this.#stringify = function_;
2530
+ }
2531
+ /**
2532
+ * Processes log metadata to format messages.
2533
+ *
2534
+ * Applies string interpolation and custom formatters to the message
2535
+ * and contextual data in the log metadata.
2536
+ * @param meta The log metadata to process
2537
+ * @returns The processed metadata with formatted messages
2538
+ */
2539
+ process(meta) {
2540
+ const formatter = build({
2541
+ formatters: this.#formatters});
2542
+ if (meta.message !== void 0) {
2543
+ meta.message = this.#format(formatter, meta.message, meta.context ?? []);
2544
+ }
2545
+ return meta;
2546
+ }
2547
+ /**
2548
+ * Recursively formats data using the formatter.
2549
+ *
2550
+ * Applies string interpolation and formatting to strings, arrays, and objects.
2551
+ * @param formatter The formatter function to use
2552
+ * @param data The data to format (string, array, or object)
2553
+ * @param arguments_ Additional arguments for formatting
2554
+ * @returns The formatted data
2555
+ * @private
2556
+ */
2557
+ #format(formatter, data, arguments_ = []) {
2558
+ if (typeof data === "string") {
2559
+ return formatter(data, arguments_);
2560
+ }
2561
+ if (typeof data === "object" && data !== null) {
2562
+ const record = data;
2563
+ const keys = Object.keys(record);
2564
+ for (let i = 0; i < keys.length; i += 1) {
2565
+ const index = keys[i];
2566
+ const value = record[index];
2567
+ if (typeof value === "string" || Array.isArray(value) || typeof value === "object") {
2568
+ record[index] = this.#format(formatter, value, arguments_);
2569
+ }
2570
+ }
2571
+ }
2572
+ return data;
2573
+ }
2574
+ }
2575
+
2576
+ const PAIL_DIST_REGEX = /[\\/]pail[\\/]dist/;
2577
+ const pailFileFilter = (line) => !PAIL_DIST_REGEX.test(line);
2578
+ class PrettyReporter extends AbstractPrettyReporter {
2579
+ #stdout;
2580
+ #stderr;
2581
+ #interactiveManager;
2582
+ #interactive = false;
2583
+ #inspectOptions;
2584
+ #errorOptions;
2585
+ /**
2586
+ * Creates a new Server Pretty Reporter instance.
2587
+ * @param options Configuration options for styling, error rendering, and object inspection
2588
+ */
2589
+ constructor(options = {}) {
2590
+ const { error: errorOptions, inspect: inspectOptions, ...rest } = options;
2591
+ super({
2592
+ uppercase: {
2593
+ label: true,
2594
+ ...rest.uppercase
2595
+ },
2596
+ ...rest
2597
+ });
2598
+ this.#inspectOptions = { ...defaultInspectorConfig, ...inspectOptions };
2599
+ this.#errorOptions = {
2600
+ ...errorOptions,
2601
+ color: {
2602
+ fileLine: green,
2603
+ hint: cyan,
2604
+ marker: red,
2605
+ message: red,
2606
+ method: greenBright,
2607
+ title: red
2608
+ }
2609
+ };
2610
+ this.#stdout = stdout;
2611
+ this.#stderr = stderr;
2612
+ }
2613
+ /**
2614
+ * Sets the stdout stream for the reporter.
2615
+ * @param stdout_ The writable stream to use for standard output
2616
+ */
2617
+ setStdout(stdout_) {
2618
+ this.#stdout = stdout_;
2619
+ }
2620
+ /**
2621
+ * Sets the stderr stream for the reporter.
2622
+ * @param stderr_ The writable stream to use for error output
2623
+ */
2624
+ setStderr(stderr_) {
2625
+ this.#stderr = stderr_;
2626
+ }
2627
+ /**
2628
+ * Sets the interactive manager for handling interactive output.
2629
+ * @param manager The interactive manager instance, or undefined to disable
2630
+ */
2631
+ setInteractiveManager(manager) {
2632
+ this.#interactiveManager = manager;
2633
+ }
2634
+ /**
2635
+ * Enables or disables interactive mode.
2636
+ * @param interactive Whether to enable interactive terminal features
2637
+ */
2638
+ setIsInteractive(interactive) {
2639
+ this.#interactive = interactive;
2640
+ }
2641
+ log(meta) {
2642
+ this._log(this._formatMessage(meta), meta.type.level);
2643
+ }
2644
+ // eslint-disable-next-line sonarjs/cognitive-complexity, no-underscore-dangle
2645
+ _formatMessage(data) {
2646
+ const { columns } = terminalSize();
2647
+ let size = columns;
2648
+ if (typeof this.styles.messageLength === "number") {
2649
+ size = this.styles.messageLength;
2650
+ }
2651
+ const { badge, context, date, error, file, groups, label, message, prefix, repeated, scope, suffix, traceError, type } = data;
2652
+ const { color } = this.loggerTypes[type.name];
2653
+ const colorized = color ? colorize[color] : white;
2654
+ const groupSpaces = groups.map(() => " ").join("");
2655
+ const items = [];
2656
+ if (groups.length > 0) {
2657
+ items.push(`${groupSpaces + grey(`[${groups.at(-1) ?? ""}]`)} `);
2658
+ }
2659
+ if (date) {
2660
+ items.push(`${grey(this.styles.dateFormatter(typeof date === "string" ? new Date(date) : date))} `);
2661
+ }
2662
+ if (badge) {
2663
+ items.push(colorized(badge));
2664
+ } else {
2665
+ const longestBadge = getLongestBadge(this.loggerTypes);
2666
+ if (longestBadge.length > 0) {
2667
+ items.push(`${grey(".".repeat(longestBadge.length))} `);
2668
+ }
2669
+ }
2670
+ const longestLabel = getLongestLabel(this.loggerTypes);
2671
+ if (label) {
2672
+ const longestLabelWidth = getStringWidth(longestLabel);
2673
+ const labelWidth = getStringWidth(label);
2674
+ items.push(`${colorized(formatLabel(label, this.styles))} `, grey(".".repeat(Math.max(0, longestLabelWidth - labelWidth))));
2675
+ } else {
2676
+ items.push(grey(".".repeat(longestLabel.length + 2)));
2677
+ }
2678
+ if (repeated) {
2679
+ items.push(`${bgGrey.white(`[${String(repeated)}x]`)} `);
2680
+ }
2681
+ if (Array.isArray(scope) && scope.length > 0) {
2682
+ items.push(` ${grey(`[${scope.join(" > ")}]`)} `);
2683
+ }
2684
+ if (prefix) {
2685
+ items.push(`${grey(`${Array.isArray(scope) && scope.length > 0 ? ". " : " "}[${this.styles.underline.prefix ? underline(prefix) : prefix}]`)} `);
2686
+ }
2687
+ const titleSize = getStringWidth(items.join(" "));
2688
+ if (file) {
2689
+ const fileMessage = (file.name ?? "") + (file.line ? `:${String(file.line)}` : "");
2690
+ const fileMessageSize = getStringWidth(fileMessage);
2691
+ if (fileMessageSize + titleSize + 2 > size) {
2692
+ items.push(grey(` ${fileMessage}`));
2693
+ } else {
2694
+ const dots = Math.max(0, size - titleSize - fileMessageSize - 2);
2695
+ items.push(grey(`${".".repeat(dots)} ${fileMessage}`));
2696
+ }
2697
+ } else {
2698
+ items.push(grey(".".repeat(Math.max(0, size - titleSize - 1))));
2699
+ }
2700
+ if (items.length > 0) {
2701
+ items.push("\n\n");
2702
+ }
2703
+ if (message !== EMPTY_SYMBOL) {
2704
+ const formattedMessage = typeof message === "string" ? message : inspect(message, this.#inspectOptions);
2705
+ items.push(
2706
+ groupSpaces + wordWrap(formattedMessage, {
2707
+ trim: false,
2708
+ width: size - 3,
2709
+ wrapMode: WrapMode.STRICT_WIDTH
2710
+ })
2711
+ );
2712
+ }
2713
+ if (context) {
2714
+ let hasError = false;
2715
+ items.push(
2716
+ ...context.map((value) => {
2717
+ if (value instanceof Error) {
2718
+ hasError = true;
2719
+ return `
2720
+
2721
+ ${renderError(value, {
2722
+ ...this.#errorOptions,
2723
+ filterStacktrace: pailFileFilter,
2724
+ prefix: groupSpaces
2725
+ })}`;
2726
+ }
2727
+ if (typeof value === "object") {
2728
+ return ` ${inspect(value, this.#inspectOptions)}`;
2729
+ }
2730
+ const newValue = (hasError ? "\n\n" : " ") + String(value);
2731
+ hasError = false;
2732
+ return newValue;
2733
+ })
2734
+ );
2735
+ }
2736
+ if (error) {
2737
+ items.push(
2738
+ renderError(error, {
2739
+ ...this.#errorOptions,
2740
+ filterStacktrace: pailFileFilter,
2741
+ prefix: groupSpaces
2742
+ })
2743
+ );
2744
+ }
2745
+ if (traceError) {
2746
+ items.push(
2747
+ `
2748
+
2749
+ ${renderError(traceError, {
2750
+ ...this.#errorOptions,
2751
+ filterStacktrace: pailFileFilter,
2752
+ hideErrorCauseCodeView: true,
2753
+ hideErrorCodeView: true,
2754
+ hideErrorErrorsCodeView: true,
2755
+ hideMessage: true,
2756
+ prefix: groupSpaces
2757
+ })}`
2758
+ );
2759
+ }
2760
+ if (suffix) {
2761
+ items.push("\n", groupSpaces + grey(this.styles.underline.suffix ? underline(suffix) : suffix));
2762
+ }
2763
+ return items.join("");
2764
+ }
2765
+ // eslint-disable-next-line no-underscore-dangle
2766
+ _log(message, logLevel) {
2767
+ const streamType = ["error", "trace", "warn"].includes(logLevel) ? "stderr" : "stdout";
2768
+ const stream = streamType === "stderr" ? this.#stderr : this.#stdout;
2769
+ if (this.#interactive && this.#interactiveManager !== void 0 && stream.isTTY) {
2770
+ this.#interactiveManager.update(streamType, message.split("\n"), 0);
2771
+ } else {
2772
+ writeStream(`${message}
2773
+ `, stream);
2774
+ }
2775
+ }
2776
+ }
2777
+
508
2778
  const getDefaultLogLevel = () => {
509
2779
  if (env.NODE_ENV === "debug" || env.DEBUG !== void 0) {
510
2780
  return "debug";
@@ -530,4 +2800,4 @@ const createPail = (options) => {
530
2800
  };
531
2801
  const pail = createPail();
532
2802
 
533
- export { MultiProgressBar, MultiSpinner, ProgressBar, Spinner, createPail, pail };
2803
+ export { createPail, pail };