@visulima/pail 3.2.2 → 4.0.0-alpha.10

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 (82) hide show
  1. package/CHANGELOG.md +188 -0
  2. package/LICENSE.md +434 -6
  3. package/README.md +355 -24
  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 -1
  9. package/dist/index.server.js +2668 -14
  10. package/dist/interactive/index.js +2 -2
  11. package/dist/middleware/elysia.d.ts +71 -0
  12. package/dist/middleware/elysia.js +70 -0
  13. package/dist/middleware/express.d.ts +86 -0
  14. package/dist/middleware/express.js +29 -0
  15. package/dist/middleware/fastify.d.ts +81 -0
  16. package/dist/middleware/fastify.js +46 -0
  17. package/dist/middleware/hono.d.ts +85 -0
  18. package/dist/middleware/hono.js +33 -0
  19. package/dist/middleware/next/handler.d.ts +36 -0
  20. package/dist/middleware/next/handler.js +53 -0
  21. package/dist/middleware/next/middleware.d.ts +59 -0
  22. package/dist/middleware/next/storage.d.ts +14 -0
  23. package/dist/middleware/shared/create-middleware-logger.d.ts +82 -0
  24. package/dist/middleware/shared/headers.d.ts +14 -0
  25. package/dist/middleware/shared/routes.d.ts +30 -0
  26. package/dist/middleware/shared/storage.d.ts +29 -0
  27. package/dist/middleware/sveltekit.d.ts +123 -0
  28. package/dist/middleware/sveltekit.js +43 -0
  29. package/dist/object-tree.d.ts +2 -2
  30. package/dist/object-tree.js +7 -7
  31. package/dist/packem_shared/{AbstractJsonReporter-intFdT_A.js → AbstractJsonReporter-CjtVgHbU.js} +112 -28
  32. package/dist/packem_shared/AbstractJsonReporter-DlugSJpY.js +288 -0
  33. package/dist/packem_shared/{InteractiveManager-CZ85hGNW.js → InteractiveManager-CowYA3Hx.js} +17 -11
  34. package/dist/packem_shared/{interactive-stream-hook-DG4BtN12.js → InteractiveStreamHook-BypRlYTX.js} +3 -11
  35. package/dist/packem_shared/{JsonReporter-C0AXk99i.js → JsonReporter-BgPvIyC2.js} +2 -2
  36. package/dist/packem_shared/{JsonReporter-DcM2LBX9.js → JsonReporter-Dbw82ewj.js} +2 -2
  37. package/dist/packem_shared/{PrettyReporter-CuLLKr6-.js → PrettyReporter-C2dCzIaf.js} +54 -8
  38. package/dist/packem_shared/{format-label-Btft2KGP.js → PrettyReporter-gMqa7j_m.js} +372 -78
  39. package/dist/packem_shared/Spinner-Cokext9b.js +2183 -0
  40. package/dist/packem_shared/abstract-pretty-reporter-szQO-IgK.js +2635 -0
  41. package/dist/packem_shared/constants-B1RjD_ps.js +99 -0
  42. package/dist/packem_shared/{constants-DfDr4MHC.js → constants-omsTHUWB.js} +1 -1
  43. package/dist/packem_shared/createPailError-B_sgL0nF.js +76 -0
  44. package/dist/packem_shared/getBarChar-D7JfmdTr.js +459 -0
  45. package/dist/packem_shared/headers-BxHWM6KI.js +127 -0
  46. package/dist/packem_shared/{index-DqKWykfa.js → index-BEfVUy9P.js} +174 -64
  47. package/dist/packem_shared/{index-BomQ3E6J.js → index-Bx3-C0j9.js} +29 -21
  48. package/dist/packem_shared/pailMiddleware-Ci88geIF.js +24 -0
  49. package/dist/packem_shared/storage-D0vqz8OX.js +36 -0
  50. package/dist/packem_shared/{InteractiveStreamHook-DiSubbJ1.js → useLogger-D0rU3lcX.js} +13 -1
  51. package/dist/packem_shared/{write-console-log-based-on-level-DBmRYXpj.js → write-console-log-based-on-level-ree2lDPw.js} +5 -4
  52. package/dist/packem_shared/{write-stream-BG8fhcs3.js → write-stream-BuFtjATz.js} +1 -1
  53. package/dist/pail.browser.d.ts +1 -1
  54. package/dist/processor/environment-processor.d.ts +124 -0
  55. package/dist/processor/environment-processor.js +82 -0
  56. package/dist/processor/message-formatter-processor.d.ts +2 -2
  57. package/dist/processor/message-formatter-processor.js +654 -6
  58. package/dist/processor/opentelemetry-processor.js +4 -4
  59. package/dist/processor/redact-processor.d.ts +1 -1
  60. package/dist/processor/redact-processor.js +2 -1
  61. package/dist/processor/sampling-processor.d.ts +111 -0
  62. package/dist/processor/sampling-processor.js +59 -0
  63. package/dist/progress-bar.d.ts +10 -1
  64. package/dist/progress-bar.js +75 -20
  65. package/dist/reporter/file/json-file-reporter.js +1 -1
  66. package/dist/reporter/http/abstract-http-reporter.js +23 -26
  67. package/dist/reporter/http/http-reporter.edge-light.js +134 -53
  68. package/dist/reporter/json/abstract-json-reporter.d.ts +1 -1
  69. package/dist/reporter/json/index.browser.js +2 -2
  70. package/dist/reporter/json/index.js +2 -2
  71. package/dist/reporter/pretty/index.browser.js +1 -1
  72. package/dist/reporter/pretty/index.js +1 -1
  73. package/dist/reporter/simple/simple-reporter.server.js +8 -12
  74. package/dist/spinner.js +37 -4
  75. package/dist/types.d.ts +4 -4
  76. package/dist/wide-event.d.ts +300 -0
  77. package/dist/wide-event.js +283 -0
  78. package/package.json +73 -8
  79. package/dist/packem_shared/PrettyReporter-BFWaYP_J.js +0 -222
  80. package/dist/packem_shared/abstract-pretty-reporter-DMPDCslJ.js +0 -50
  81. package/dist/packem_shared/get-longest-label-C9PWeyKq.js +0 -9
  82. package/dist/packem_shared/pail.browser-CPjQrsyy.js +0 -1427
@@ -17,17 +17,24 @@ const __cjs_getBuiltinModule = (module) => {
17
17
  return __cjs_require(module);
18
18
  };
19
19
 
20
+ const {
21
+ stdout,
22
+ stderr
23
+ } = __cjs_getProcess;
24
+ import colorize, { grey, green, cyan, red, yellow, bold, magenta, underline, greenBright, bgGrey, white } from '@visulima/colorize';
25
+ import { t as terminalSize, g as getStringWidth, w as wordWrap, W as WrapMode } from './index-BEfVUy9P.js';
26
+ import { L as LOG_TYPES, E as EMPTY_SYMBOL } from './constants-B1RjD_ps.js';
27
+ import { w as writeStream } from './write-stream-BuFtjATz.js';
20
28
  const {
21
29
  createRequire
22
30
  } = __cjs_getBuiltinModule("node:module");
23
- import { grey, green, cyan, red, yellow, bold, magenta, underline } from '@visulima/colorize';
24
31
 
25
32
  const normalizeLF = (code) => code.replaceAll(/\r\n|\r(?!\n)|\n/gu, "\n");
26
- const _process = globalThis.process || /* @__PURE__ */ Object.create(null);
33
+ const rawProcess = globalThis.process ?? /* @__PURE__ */ Object.create(null);
27
34
  const processShims = {
28
35
  versions: {}
29
36
  };
30
- const process$1 = new Proxy(_process, {
37
+ const process$1 = /* @__PURE__ */ new Proxy(rawProcess, {
31
38
  get(target, property) {
32
39
  if (property in target) {
33
40
  return target[property];
@@ -102,9 +109,9 @@ const codeFrame = (source, loc, options) => {
102
109
  ...options?.color
103
110
  }
104
111
  };
105
- const hasColumns = loc.start && typeof loc.start.column === "number";
112
+ const hasColumns = typeof loc.start.column === "number";
106
113
  let lines = normalizeLF(source).split("\n");
107
- if (typeof config?.tabWidth === "number") {
114
+ if (typeof config.tabWidth === "number") {
108
115
  lines = lines.map((ln) => ln.replaceAll(" ", " ".repeat(config.tabWidth)));
109
116
  }
110
117
  const { end, markerLines, start } = getMarkerLines(loc, lines, config.linesAbove, config.linesBelow);
@@ -113,7 +120,7 @@ const codeFrame = (source, loc, options) => {
113
120
  let frame = lines.slice(start, end).map((line, index) => {
114
121
  const number = start + 1 + index;
115
122
  const hasMarker = markerLines[number];
116
- const paddedNumber = ` ${number}`.slice(-numberMaxWidth);
123
+ const paddedNumber = ` ${String(number)}`.slice(-numberMaxWidth);
117
124
  const lastMarkerLine = !markerLines[number + 1];
118
125
  const gutter = ` ${paddedNumber}${config.showGutter ? " |" : ""}`;
119
126
  if (hasMarker) {
@@ -144,15 +151,15 @@ ${frame}`;
144
151
  };
145
152
 
146
153
  const debugLog = (message, ...arguments_) => {
147
- if (process.env.DEBUG && String(process.env.DEBUG) === "true") {
154
+ if (process.env.DEBUG && process.env.DEBUG === "true") {
148
155
  console.debug(`error:parse-stacktrace: ${message}`, ...arguments_);
149
156
  }
150
157
  };
151
158
  const UNKNOWN_FUNCTION = "<unknown>";
152
159
  const CHROMIUM_REGEX = /^.*?\s*at\s(?:(.+?\)(?:\s\[.+\])?|\(?.*?)\s?\((?:address\sat\s)?)?(?:async\s)?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
153
160
  const CHROMIUM_EVAL_REGEX = /\((\S+)\),\s(<[^>]+>)?:(\d+)?:(\d+)?\)?/;
154
- const CHROMIUM_MAPPED = /(.*?):(\d+):(\d+)(\s<-\s(.+):(\d+):(\d+))?/;
155
- const WINDOWS_EVAL_REGEX = /(eval)\sat\s(<anonymous>)\s\((.*)\)?:(\d+)?:(\d+)\),\s*(<anonymous>)?:(\d+)?:(\d+)/;
161
+ const CHROMIUM_MAPPED = /(.*?):(\d+):(\d+)(?:\s<-\s.+:\d+:\d+)?/;
162
+ const WINDOWS_EVAL_REGEX = /eval\sat\s(<anonymous>)\s\((.*)\)?:(\d+)?:(\d+)\),\s*<anonymous>?:(\d+)?:(\d+)/;
156
163
  const NODE_REGEX = /^\s*in\s(?:([^\\/]+(?:\s\[as\s\S+\])?)\s\(?)?\(at?\s?(.*?):(\d+)(?::(\d+))?\)?\s*$/;
157
164
  const NODE_NESTED_REGEX = /in\s(.*)\s\(at\s(.+)\)\sat/;
158
165
  const REACT_ANDROID_NATIVE_REGEX = /^(?:.*@)?(.*):(\d+):(\d+)$/;
@@ -160,6 +167,14 @@ const GECKO_REGEX = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native
160
167
  const GECKO_EVAL_REGEX = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
161
168
  const FIREFOX_REGEX = /(\S[^\s[]*\[.*\]|.*?)@(.*):(\d+):(\d+)/;
162
169
  const WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
170
+ const AT_PREFIX_REGEX = /at\s/;
171
+ const CHROMIUM_EVAL_SPLIT_REGEX = /^(\S+):(\d+):(\d+)$|^(\S+):(\d+)$/;
172
+ const TRIM_REGEX = /^\s+|\s+$/g;
173
+ const ERROR_LINE_REGEX = /\S*(?:Error: |AggregateError:)/;
174
+ const ANONYMOUS_FUNCTION_REGEX = /^Anonymous function$/;
175
+ const NODE_LINE_REGEX = /^\s*in\s.*/;
176
+ const CHROMIUM_LINE_REGEX = /^.*?\s*at\s.*/;
177
+ const GECKO_LINE_REGEX = /^.*?\s*@.*|\[native code\]/;
163
178
  const extractSafariExtensionDetails = (methodName, url) => {
164
179
  const isSafariExtension = methodName.includes("safari-extension");
165
180
  const isSafariWebExtension = methodName.includes("safari-web-extension");
@@ -185,7 +200,7 @@ const parseNode = (line) => {
185
200
  column: split[2] ? +split[2] : void 0,
186
201
  file: split[0],
187
202
  line: split[1] ? +split[1] : void 0,
188
- methodName: nestedNode[1] || UNKNOWN_FUNCTION,
203
+ methodName: nestedNode[1] ?? UNKNOWN_FUNCTION,
189
204
  raw: line,
190
205
  type: void 0
191
206
  };
@@ -195,9 +210,9 @@ const parseNode = (line) => {
195
210
  debugLog(`parse node error stack line: "${line}"`, `found: ${JSON.stringify(node)}`);
196
211
  const trace = {
197
212
  column: node[4] ? +node[4] : void 0,
198
- file: node[2] ? node[2].replace(/at\s/, "") : void 0,
213
+ file: node[2] ? node[2].replace(AT_PREFIX_REGEX, "") : void 0,
199
214
  line: node[3] ? +node[3] : void 0,
200
- methodName: node[1] || UNKNOWN_FUNCTION,
215
+ methodName: node[1] ?? UNKNOWN_FUNCTION,
201
216
  raw: line,
202
217
  type: line.startsWith("internal") ? "internal" : void 0
203
218
  };
@@ -217,7 +232,7 @@ const parseChromium = (line) => {
217
232
  if (isEval) {
218
233
  const subMatch = CHROMIUM_EVAL_REGEX.exec(line);
219
234
  if (subMatch) {
220
- const split = /^(\S+):(\d+):(\d+)$|^(\S+):(\d+)$/.exec(subMatch[1]);
235
+ const split = CHROMIUM_EVAL_SPLIT_REGEX.exec(subMatch[1]);
221
236
  if (split) {
222
237
  parts[2] = split[4] ?? split[1];
223
238
  parts[3] = split[5] ?? split[2];
@@ -239,14 +254,14 @@ const parseChromium = (line) => {
239
254
  const windowsSubMatch = WINDOWS_EVAL_REGEX.exec(line);
240
255
  if (windowsSubMatch) {
241
256
  windowsParts = {
242
- column: windowsSubMatch[5] ? +windowsSubMatch[5] : void 0,
243
- file: windowsSubMatch[3],
244
- line: windowsSubMatch[4] ? +windowsSubMatch[4] : void 0
257
+ column: windowsSubMatch[4] ? +windowsSubMatch[4] : void 0,
258
+ file: windowsSubMatch[2],
259
+ line: windowsSubMatch[3] ? +windowsSubMatch[3] : void 0
245
260
  };
246
261
  evalOrigin = {
247
- column: windowsSubMatch[8] ? +windowsSubMatch[8] : void 0,
248
- file: windowsSubMatch[2],
249
- line: windowsSubMatch[7] ? +windowsSubMatch[7] : void 0,
262
+ column: windowsSubMatch[6] ? +windowsSubMatch[6] : void 0,
263
+ file: windowsSubMatch[1],
264
+ line: windowsSubMatch[5] ? +windowsSubMatch[5] : void 0,
250
265
  methodName: "eval",
251
266
  raw: windowsSubMatch[0],
252
267
  type: "eval"
@@ -256,7 +271,7 @@ const parseChromium = (line) => {
256
271
  }
257
272
  const [methodName, file] = extractSafariExtensionDetails(
258
273
  // Normalize IE's 'Anonymous function'
259
- parts[1] ? parts[1].replace(/^Anonymous function$/, "<anonymous>") : UNKNOWN_FUNCTION,
274
+ parts[1] ? parts[1].replace(ANONYMOUS_FUNCTION_REGEX, "<anonymous>") : UNKNOWN_FUNCTION,
260
275
  parts[2]
261
276
  );
262
277
  const trace = {
@@ -301,7 +316,7 @@ const parseGecko = (line, topFrameMeta) => {
301
316
  }
302
317
  const [methodName, file] = extractSafariExtensionDetails(
303
318
  // Normalize IE's 'Anonymous function'
304
- parts[1] ? parts[1].replace(/^Anonymous function$/, "<anonymous>") : UNKNOWN_FUNCTION,
319
+ parts[1] ? parts[1].replace(ANONYMOUS_FUNCTION_REGEX, "<anonymous>") : UNKNOWN_FUNCTION,
305
320
  parts[3]
306
321
  );
307
322
  let column;
@@ -338,6 +353,7 @@ const parseFirefox = (line, topFrameMeta) => {
338
353
  column: parts[4] ? +parts[4] : topFrameMeta?.column ?? void 0,
339
354
  file: parts[2],
340
355
  line: parts[3] ? +parts[3] : topFrameMeta?.line ?? void 0,
356
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentionally using || to treat empty string as unknown
341
357
  methodName: parts[1] || UNKNOWN_FUNCTION,
342
358
  raw: line,
343
359
  type: void 0
@@ -361,10 +377,12 @@ const parseReactAndroidNative = (line) => {
361
377
  return void 0;
362
378
  };
363
379
  const parseStacktrace = (error, { filter, frameLimit = 50 } = {}) => {
364
- let lines = (error.stacktrace ?? error.stack ?? "").split("\n").map((line) => {
380
+ const errorRecord = error;
381
+ const rawStack = typeof errorRecord.stacktrace === "string" ? errorRecord.stacktrace : error.stack ?? "";
382
+ let lines = rawStack.split("\n").map((line) => {
365
383
  const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, "$1") : line;
366
- return cleanedLine.replace(/^\s+|\s+$/g, "");
367
- }).filter((line) => !/\S*(?:Error: |AggregateError:)/.test(line) && line !== "eval code");
384
+ return cleanedLine.replaceAll(TRIM_REGEX, "");
385
+ }).filter((line) => !ERROR_LINE_REGEX.test(line) && line !== "eval code");
368
386
  if (filter) {
369
387
  lines = lines.filter((element) => filter(element));
370
388
  }
@@ -377,32 +395,33 @@ const parseStacktrace = (error, { filter, frameLimit = 50 } = {}) => {
377
395
  return stack;
378
396
  }
379
397
  let parseResult;
380
- if (/^\s*in\s.*/.test(line)) {
398
+ if (NODE_LINE_REGEX.test(line)) {
381
399
  parseResult = parseNode(line);
382
- } else if (/^.*?\s*at\s.*/.test(line)) {
400
+ } else if (CHROMIUM_LINE_REGEX.test(line)) {
383
401
  parseResult = parseChromium(line);
384
- } else if (/^.*?\s*@.*|\[native code\]/.test(line)) {
402
+ } else if (GECKO_LINE_REGEX.test(line)) {
385
403
  let topFrameMeta;
386
404
  if (currentIndex === 0) {
387
- if (error.columnNumber || error.lineNumber) {
405
+ const browserError = error;
406
+ const columnNumber = browserError.columnNumber;
407
+ const lineNumber = browserError.lineNumber;
408
+ const safariLine = browserError.line;
409
+ const safariColumn = browserError.column;
410
+ if (columnNumber || lineNumber) {
388
411
  topFrameMeta = {
389
- // @ts-expect-error columnNumber and columnNumber property only exists on Firefox
390
- column: error.columnNumber,
391
- // @ts-expect-error columnNumber and lineNumber property only exists on Firefox
392
- line: error.lineNumber,
412
+ column: columnNumber,
413
+ line: lineNumber,
393
414
  type: "firefox"
394
415
  };
395
- } else if (error.line || error.column) {
416
+ } else if (safariLine || safariColumn) {
396
417
  topFrameMeta = {
397
- // @ts-expect-error column property only exists on safari
398
- column: error.column,
399
- // @ts-expect-error line property only exists on safari
400
- line: error.line,
418
+ column: safariColumn,
419
+ line: safariLine,
401
420
  type: "safari"
402
421
  };
403
422
  }
404
423
  }
405
- parseResult = parseFirefox(line, topFrameMeta) || parseGecko(line, topFrameMeta);
424
+ parseResult = parseFirefox(line, topFrameMeta) ?? parseGecko(line, topFrameMeta);
406
425
  } else {
407
426
  parseResult = parseReactAndroidNative(line);
408
427
  }
@@ -430,7 +449,7 @@ const {
430
449
  } = __cjs_getBuiltinModule("node:url");
431
450
  const getPrefix = (prefix, indentation, deep) => {
432
451
  if (deep === 0) {
433
- return prefix.toString();
452
+ return prefix;
434
453
  }
435
454
  if (indentation === " ") {
436
455
  return prefix + " ".repeat(deep);
@@ -458,7 +477,7 @@ const getHint = (error, { color, indentation, prefix }, deep) => {
458
477
  let message = "";
459
478
  if (Array.isArray(error.hint)) {
460
479
  for (const line of error.hint) {
461
- message += `${(spaces + line).toString()}
480
+ message += `${spaces + line}
462
481
  `;
463
482
  }
464
483
  } else {
@@ -471,7 +490,7 @@ const getMainFrame = (trace, { color, cwd: cwdPath, displayShortPath, indentatio
471
490
  const { fileLine, method } = color;
472
491
  return `${getPrefix(prefix, indentation, deep)}at ${trace.methodName ? `${method(trace.methodName)} ` : ""}${fileLine(filePath)}:${fileLine(
473
492
  trace.line?.toString() ?? ""
474
- )}`.toString();
493
+ )}`;
475
494
  };
476
495
  const getCode = (trace, { color, indentation, linesAbove, linesBelow, prefix, showGutter, showLineNumbers, tabWidth }, deep) => {
477
496
  if (trace.file === void 0) {
@@ -615,7 +634,7 @@ const inspectList = (list, from, options, inspect2, inspectItem, separator = ",
615
634
  for (let index = 0; index < size; index += 1) {
616
635
  const last = index + 1 === list.length;
617
636
  const secondToLast = index + 2 === list.length;
618
- truncated = `${TRUNCATOR}(${list.length - index})`;
637
+ truncated = `${TRUNCATOR}(${String(list.length - index)})`;
619
638
  let value = list[index];
620
639
  options.truncate = originalLength - output.length - (last ? 0 : separator.length);
621
640
  const string = peek || inspect_(value, from, options, inspect2) + (last ? "" : separator);
@@ -628,13 +647,18 @@ const inspectList = (list, from, options, inspect2, inspectItem, separator = ",
628
647
  break;
629
648
  }
630
649
  value = list[index + 1];
631
- peek = last ? "" : inspect_(value, from, options, inspect2) + (secondToLast ? "" : separator);
650
+ const peekSuffix = secondToLast ? "" : separator;
651
+ if (last) {
652
+ peek = "";
653
+ } else {
654
+ peek = inspect_(value, from, options, inspect2) + peekSuffix;
655
+ }
632
656
  if (!last && secondToLast && truncatedLength > originalLength && nextLength + peek.length > originalLength) {
633
657
  break;
634
658
  }
635
659
  output += string;
636
660
  if (!last && !secondToLast && nextLength + peek.length >= originalLength) {
637
- truncated = `${TRUNCATOR}(${list.length - index - 1})`;
661
+ truncated = `${TRUNCATOR}(${String(list.length - index - 1)})`;
638
662
  break;
639
663
  }
640
664
  truncated = "";
@@ -685,7 +709,7 @@ const inspectHTMLElement = (element, object, options, inspect2) => {
685
709
  const { truncate: truncate2 } = options;
686
710
  let children = inspectNodeCollection(element.children, options, inspect2);
687
711
  if (children && children.length > truncate2) {
688
- children = `${TRUNCATOR}(${element.children.length})`;
712
+ children = `${TRUNCATOR}(${String(element.children.length)})`;
689
713
  }
690
714
  return `${head}${propertyContents}${headClose}${children}${tail}`;
691
715
  };
@@ -718,26 +742,31 @@ const indentedJoin = (values, indent) => {
718
742
  const lineJoiner = indent.prev + indent.base;
719
743
  return lineJoiner + values.split(", ").join(`,${lineJoiner}`) + indent.prev;
720
744
  };
745
+ const simpleKeyRegex = /^[a-z_]\w*$/i;
746
+ const quoteEdgesRegex = /^"|"$/g;
721
747
  const quoteComplexKey = (key, options) => {
722
- if (/^[a-z_]\w*$/i.test(key)) {
748
+ if (simpleKeyRegex.test(key)) {
723
749
  return key;
724
750
  }
725
751
  const stringifiedKey = JSON.stringify(key);
726
752
  if (options.quoteStyle === "double") {
727
753
  return stringifiedKey.replaceAll('"', String.raw`\"`);
728
754
  }
729
- return stringifiedKey.replaceAll("'", String.raw`\'`).replaceAll(String.raw`\"`, '"').replaceAll(/^"|"$/g, "'");
755
+ return stringifiedKey.replaceAll("'", String.raw`\'`).replaceAll(String.raw`\"`, '"').replaceAll(quoteEdgesRegex, "'");
730
756
  };
731
757
  const inspectProperty = ([key, value], object, options, inspect2) => {
732
758
  options.truncate -= 2;
759
+ let keyString;
733
760
  if (typeof key === "string") {
734
- key = quoteComplexKey(key, options);
735
- } else if (typeof key !== "number") {
736
- key = `[${inspect2(key, object, options)}]`;
761
+ keyString = quoteComplexKey(key, options);
762
+ } else if (typeof key === "number") {
763
+ keyString = String(key);
764
+ } else {
765
+ keyString = `[${inspect2(key, object, options)}]`;
737
766
  }
738
- options.truncate -= key.length;
739
- value = inspect2(value, object, options);
740
- return `${key}: ${value}`;
767
+ options.truncate -= keyString.length;
768
+ const valueString = inspect2(value, object, options);
769
+ return `${keyString}: ${valueString}`;
741
770
  };
742
771
  const multiLineValues = (values) => {
743
772
  for (const value of values) {
@@ -771,11 +800,13 @@ const inspectArray = (array, options, inspect2, indent) => {
771
800
  }
772
801
  return `[${hasIndent ? "" : " "}${listContents}${propertyContents ? `, ${propertyContents}` : ""}${hasIndent ? "" : " "}]`;
773
802
  };
803
+ const separatorRegex = /\d(?=(?:\d{3})+(?!\d))/g;
804
+ const decimalGroupRegex = /\d{3}/g;
805
+ const trailingUnderscoreRegex = /_$/;
774
806
  const addNumericSeparator = (number_, string_) => {
775
807
  if (number_ === Number.POSITIVE_INFINITY || number_ === Number.NEGATIVE_INFINITY || string_.includes("e")) {
776
808
  return string_;
777
809
  }
778
- const separatorRegex = /\d(?=(?:\d{3})+(?!\d))/g;
779
810
  if (typeof number_ === "number") {
780
811
  const int = number_ < 0 ? -Math.floor(-number_) : Math.floor(number_);
781
812
  if (int !== number_) {
@@ -783,7 +814,7 @@ const addNumericSeparator = (number_, string_) => {
783
814
  const dec = string_.slice(intString.length + 1);
784
815
  return (
785
816
  // eslint-disable-next-line unicorn/prefer-string-replace-all
786
- `${intString.replace(separatorRegex, "$&_")}.${dec.replace(/\d{3}/g, "$&_").replace(/_$/, "")}`
817
+ `${intString.replace(separatorRegex, "$&_")}.${dec.replace(decimalGroupRegex, "$&_").replace(trailingUnderscoreRegex, "")}`
787
818
  );
788
819
  }
789
820
  }
@@ -815,19 +846,24 @@ const inspectBigInt = (number, options) => {
815
846
  };
816
847
  const gPO = (typeof Reflect === "function" ? Reflect.getPrototypeOf : Object.getPrototypeOf) || ([].__proto__ === Array.prototype ? function(O) {
817
848
  return O.__proto__;
818
- } : null);
849
+ } : void 0);
819
850
  const inspectObject$1 = (object, options, inspect2, indent) => {
820
- if (globalThis.window !== void 0 && object === globalThis) {
851
+ if ("window" in globalThis && object === globalThis) {
821
852
  return "{ [object Window] }";
822
853
  }
823
- if (typeof globalThis !== "undefined" && object === globalThis || globalThis.global !== void 0 && object === globalThis) {
854
+ if (object === globalThis || "global" in globalThis && object === globalThis) {
824
855
  return "{ [object globalThis] }";
825
856
  }
826
857
  const properties = Object.getOwnPropertyNames(object);
827
- const symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : [];
858
+ const symbols = Object.getOwnPropertySymbols(object);
828
859
  const isPlainObject = gPO(object) === Object.prototype || object.constructor === Object;
829
860
  const protoTag = object instanceof Object ? "" : "null prototype";
830
- const stringTag = !isPlainObject && typeof Symbol !== "undefined" && Symbol.toStringTag in object ? object[Symbol.toStringTag] : protoTag ? "Object" : "";
861
+ let stringTag;
862
+ if (!isPlainObject && Symbol.toStringTag in object) {
863
+ stringTag = object[Symbol.toStringTag];
864
+ } else {
865
+ stringTag = protoTag ? "Object" : "";
866
+ }
831
867
  const tag = stringTag || protoTag ? `[${[stringTag, protoTag].filter(Boolean).join(": ")}] ` : "";
832
868
  if (properties.length === 0 && symbols.length === 0) {
833
869
  return `${tag}{}`;
@@ -923,7 +959,7 @@ const inspectMap = (map, options, inspect2, indent) => {
923
959
  if (indent) {
924
960
  returnValue = indentedJoin(returnValue, indent);
925
961
  }
926
- return `Map (${map.size}) {${indent ? "" : " "}${returnValue}${indent ? "" : " "}}`;
962
+ return `Map (${String(map.size)}) {${indent ? "" : " "}${returnValue}${indent ? "" : " "}}`;
927
963
  };
928
964
  function inspectNumber(number, options) {
929
965
  if (Number.isNaN(number)) {
@@ -954,7 +990,7 @@ const inspectSet = (set, options, inspect2, indent) => {
954
990
  if (indent) {
955
991
  returnValue = indentedJoin(returnValue, indent);
956
992
  }
957
- return `Set (${set.size}) {${indent ? "" : " "}${returnValue}${indent ? "" : " "}}`;
993
+ return `Set (${String(set.size)}) {${indent ? "" : " "}${returnValue}${indent ? "" : " "}}`;
958
994
  };
959
995
  const wrapQuotes = (string_, options) => {
960
996
  const quoteChar = options.quoteStyle === "double" ? '"' : "'";
@@ -977,7 +1013,7 @@ const escapeCharacters = {
977
1013
  "\\": "\\\\"
978
1014
  };
979
1015
  const hex = 16;
980
- const escape = (char) => escapeCharacters[char] || `\\u${`0000${char.codePointAt(0).toString(hex)}`.slice(-4)}`;
1016
+ const escape = (char) => escapeCharacters[char] || String.raw`\u${`0000${char.codePointAt(0).toString(hex)}`.slice(-4)}`;
981
1017
  const inspectString = (string_, options) => {
982
1018
  if (stringEscapeChars.test(string_)) {
983
1019
  string_ = string_.replaceAll(stringEscapeChars, escape);
@@ -994,10 +1030,7 @@ const getArrayName = (array) => {
994
1030
  if (typeof Buffer === "function" && array instanceof Buffer) {
995
1031
  return "Buffer";
996
1032
  }
997
- if (array[Symbol.toStringTag]) {
998
- return array[Symbol.toStringTag];
999
- }
1000
- return array.constructor.name;
1033
+ return array[Symbol.toStringTag];
1001
1034
  };
1002
1035
  const inspectTypedArray = (array, options, inspect2) => {
1003
1036
  const name = getArrayName(array);
@@ -1011,7 +1044,7 @@ const inspectTypedArray = (array, options, inspect2) => {
1011
1044
  const string = `${options.stylize(truncate(array[index], options.truncate), "number")}${index === array.length - 1 ? "" : ", "}`;
1012
1045
  options.truncate -= string.length;
1013
1046
  if (array[index] !== array.length && options.truncate <= 3) {
1014
- output += `${TRUNCATOR}(${array.length - array[index] + 1})`;
1047
+ output += `${TRUNCATOR}(${String(array.length - array[index] + 1)})`;
1015
1048
  break;
1016
1049
  }
1017
1050
  output += string;
@@ -1074,9 +1107,10 @@ const baseTypesMap = {
1074
1107
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1075
1108
  WeakSet: (_value, options) => options.stylize("WeakSet{…}", "special")
1076
1109
  };
1110
+ const nodeInspectCustomSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
1077
1111
  const inspectCustom = (value, options, type, depth) => {
1078
- if (globalThis.window === void 0 && typeof value[Symbol.for("nodejs.util.inspect.custom")] === "function") {
1079
- return value[Symbol.for("nodejs.util.inspect.custom")](depth, options);
1112
+ if (!("window" in globalThis) && typeof value[nodeInspectCustomSymbol] === "function") {
1113
+ return value[nodeInspectCustomSymbol](depth, options);
1080
1114
  }
1081
1115
  if ("inspect" in value && typeof value.inspect === "function") {
1082
1116
  return value.inspect(depth, options);
@@ -1084,8 +1118,9 @@ const inspectCustom = (value, options, type, depth) => {
1084
1118
  if ("constructor" in value && constructorMap.has(value.constructor)) {
1085
1119
  return constructorMap.get(value.constructor)?.(value, options) ?? "unknown";
1086
1120
  }
1087
- if (stringTagMap[type]) {
1088
- return stringTagMap[type](value, options);
1121
+ const tagInspector = stringTagMap[type];
1122
+ if (tagInspector) {
1123
+ return tagInspector(value, options);
1089
1124
  }
1090
1125
  return "";
1091
1126
  };
@@ -1098,8 +1133,7 @@ const internalInspect = (value, options, depth, seen) => {
1098
1133
  }
1099
1134
  const inspect2 = (object, from, options2) => {
1100
1135
  if (from) {
1101
- seen = [...seen];
1102
- seen.push(from);
1136
+ seen = [...seen, from];
1103
1137
  }
1104
1138
  return internalInspect(object, options2, depth + 1, seen);
1105
1139
  };
@@ -1108,8 +1142,9 @@ const internalInspect = (value, options, depth, seen) => {
1108
1142
  if (type === "object") {
1109
1143
  type = Object.prototype.toString.call(value).slice(8, -1);
1110
1144
  }
1111
- if (baseTypesMap[type] !== void 0) {
1112
- return baseTypesMap[type](value, options, inspect2, indent);
1145
+ const baseInspector = baseTypesMap[type];
1146
+ if (baseInspector !== void 0) {
1147
+ return baseInspector(value, options, inspect2, indent);
1113
1148
  }
1114
1149
  if (options.customInspect && value) {
1115
1150
  const output = inspectCustom(value, options, type, options.depth - depth);
@@ -1149,7 +1184,7 @@ const inspect = (value, options_ = {}) => {
1149
1184
  quoteStyle: "single",
1150
1185
  showHidden: false,
1151
1186
  showProxy: false,
1152
- stylize: (s) => s.toString(),
1187
+ stylize: (s) => s,
1153
1188
  truncate: Number.POSITIVE_INFINITY,
1154
1189
  ...options_
1155
1190
  };
@@ -1159,6 +1194,22 @@ const inspect = (value, options_ = {}) => {
1159
1194
  return internalInspect(value, options, 0, []);
1160
1195
  };
1161
1196
 
1197
+ const getLongestBadge = (types) => {
1198
+ const badges = Object.keys(types).map((x) => types[x].badge ?? "");
1199
+ if (badges.length === 0) {
1200
+ return "";
1201
+ }
1202
+ return badges.reduce((x, y) => x.length > y.length ? x : y, "");
1203
+ };
1204
+
1205
+ const getLongestLabel = (types) => {
1206
+ const labels = Object.keys(types).map((x) => types[x].label ?? "");
1207
+ if (labels.length === 0) {
1208
+ return "";
1209
+ }
1210
+ return labels.reduce((x, y) => x.length > y.length ? x : y, "");
1211
+ };
1212
+
1162
1213
  const defaultInspectorConfig = {
1163
1214
  indent: 2,
1164
1215
  quoteStyle: "single",
@@ -1191,4 +1242,247 @@ const formatLabel = (label, styles) => {
1191
1242
  return formattedLabel;
1192
1243
  };
1193
1244
 
1194
- export { defaultInspectorConfig as d, formatLabel as f, inspect as i, renderError as r };
1245
+ const dateFormatter = (date) => [date.getHours(), date.getMinutes(), date.getSeconds()].map((n) => String(n).padStart(2, "0")).join(":");
1246
+ class AbstractPrettyReporter {
1247
+ /** Styling options for pretty formatting */
1248
+ styles;
1249
+ /** Logger type configurations for styling */
1250
+ loggerTypes;
1251
+ /**
1252
+ * Creates a new AbstractPrettyReporter instance.
1253
+ * @param options Styling options for pretty formatting
1254
+ * @protected
1255
+ */
1256
+ constructor(options) {
1257
+ this.styles = {
1258
+ bold: {
1259
+ label: false
1260
+ },
1261
+ dateFormatter,
1262
+ underline: {
1263
+ label: false,
1264
+ message: false,
1265
+ prefix: false,
1266
+ suffix: false
1267
+ },
1268
+ uppercase: {
1269
+ label: false
1270
+ },
1271
+ ...options
1272
+ };
1273
+ this.loggerTypes = LOG_TYPES;
1274
+ }
1275
+ /**
1276
+ * Sets the logger types configuration for styling.
1277
+ * @param types Logger type configurations with colors and labels
1278
+ */
1279
+ setLoggerTypes(types) {
1280
+ this.loggerTypes = types;
1281
+ }
1282
+ }
1283
+
1284
+ const PAIL_DIST_REGEX = /[\\/]pail[\\/]dist/;
1285
+ const pailFileFilter = (line) => !PAIL_DIST_REGEX.test(line);
1286
+ class PrettyReporter extends AbstractPrettyReporter {
1287
+ #stdout;
1288
+ #stderr;
1289
+ #interactiveManager;
1290
+ #interactive = false;
1291
+ #inspectOptions;
1292
+ #errorOptions;
1293
+ /**
1294
+ * Creates a new Server Pretty Reporter instance.
1295
+ * @param options Configuration options for styling, error rendering, and object inspection
1296
+ */
1297
+ constructor(options = {}) {
1298
+ const { error: errorOptions, inspect: inspectOptions, ...rest } = options;
1299
+ super({
1300
+ uppercase: {
1301
+ label: true,
1302
+ ...rest.uppercase
1303
+ },
1304
+ ...rest
1305
+ });
1306
+ this.#inspectOptions = { ...defaultInspectorConfig, ...inspectOptions };
1307
+ this.#errorOptions = {
1308
+ ...errorOptions,
1309
+ color: {
1310
+ fileLine: green,
1311
+ hint: cyan,
1312
+ marker: red,
1313
+ message: red,
1314
+ method: greenBright,
1315
+ title: red
1316
+ }
1317
+ };
1318
+ this.#stdout = stdout;
1319
+ this.#stderr = stderr;
1320
+ }
1321
+ /**
1322
+ * Sets the stdout stream for the reporter.
1323
+ * @param stdout_ The writable stream to use for standard output
1324
+ */
1325
+ setStdout(stdout_) {
1326
+ this.#stdout = stdout_;
1327
+ }
1328
+ /**
1329
+ * Sets the stderr stream for the reporter.
1330
+ * @param stderr_ The writable stream to use for error output
1331
+ */
1332
+ setStderr(stderr_) {
1333
+ this.#stderr = stderr_;
1334
+ }
1335
+ /**
1336
+ * Sets the interactive manager for handling interactive output.
1337
+ * @param manager The interactive manager instance, or undefined to disable
1338
+ */
1339
+ setInteractiveManager(manager) {
1340
+ this.#interactiveManager = manager;
1341
+ }
1342
+ /**
1343
+ * Enables or disables interactive mode.
1344
+ * @param interactive Whether to enable interactive terminal features
1345
+ */
1346
+ setIsInteractive(interactive) {
1347
+ this.#interactive = interactive;
1348
+ }
1349
+ log(meta) {
1350
+ this._log(this._formatMessage(meta), meta.type.level);
1351
+ }
1352
+ // eslint-disable-next-line sonarjs/cognitive-complexity, no-underscore-dangle
1353
+ _formatMessage(data) {
1354
+ const { columns } = terminalSize();
1355
+ let size = columns;
1356
+ if (typeof this.styles.messageLength === "number") {
1357
+ size = this.styles.messageLength;
1358
+ }
1359
+ const { badge, context, date, error, file, groups, label, message, prefix, repeated, scope, suffix, traceError, type } = data;
1360
+ const { color } = this.loggerTypes[type.name];
1361
+ const colorized = color ? colorize[color] : white;
1362
+ const groupSpaces = groups.map(() => " ").join("");
1363
+ const items = [];
1364
+ if (groups.length > 0) {
1365
+ items.push(`${groupSpaces + grey(`[${groups.at(-1) ?? ""}]`)} `);
1366
+ }
1367
+ if (date) {
1368
+ items.push(`${grey(this.styles.dateFormatter(typeof date === "string" ? new Date(date) : date))} `);
1369
+ }
1370
+ if (badge) {
1371
+ items.push(colorized(badge));
1372
+ } else {
1373
+ const longestBadge = getLongestBadge(this.loggerTypes);
1374
+ if (longestBadge.length > 0) {
1375
+ items.push(`${grey(".".repeat(longestBadge.length))} `);
1376
+ }
1377
+ }
1378
+ const longestLabel = getLongestLabel(this.loggerTypes);
1379
+ if (label) {
1380
+ const longestLabelWidth = getStringWidth(longestLabel);
1381
+ const labelWidth = getStringWidth(label);
1382
+ items.push(`${colorized(formatLabel(label, this.styles))} `, grey(".".repeat(Math.max(0, longestLabelWidth - labelWidth))));
1383
+ } else {
1384
+ items.push(grey(".".repeat(longestLabel.length + 2)));
1385
+ }
1386
+ if (repeated) {
1387
+ items.push(`${bgGrey.white(`[${String(repeated)}x]`)} `);
1388
+ }
1389
+ if (Array.isArray(scope) && scope.length > 0) {
1390
+ items.push(` ${grey(`[${scope.join(" > ")}]`)} `);
1391
+ }
1392
+ if (prefix) {
1393
+ items.push(
1394
+ `${grey(`${Array.isArray(scope) && scope.length > 0 ? ". " : " "}[${this.styles.underline.prefix ? underline(prefix) : prefix}]`)} `
1395
+ );
1396
+ }
1397
+ const titleSize = getStringWidth(items.join(" "));
1398
+ if (file) {
1399
+ const fileMessage = (file.name ?? "") + (file.line ? `:${String(file.line)}` : "");
1400
+ const fileMessageSize = getStringWidth(fileMessage);
1401
+ if (fileMessageSize + titleSize + 2 > size) {
1402
+ items.push(grey(` ${fileMessage}`));
1403
+ } else {
1404
+ const dots = Math.max(0, size - titleSize - fileMessageSize - 2);
1405
+ items.push(grey(`${".".repeat(dots)} ${fileMessage}`));
1406
+ }
1407
+ } else {
1408
+ items.push(grey(".".repeat(Math.max(0, size - titleSize - 1))));
1409
+ }
1410
+ if (items.length > 0) {
1411
+ items.push("\n\n");
1412
+ }
1413
+ if (message !== EMPTY_SYMBOL) {
1414
+ const formattedMessage = typeof message === "string" ? message : inspect(message, this.#inspectOptions);
1415
+ items.push(
1416
+ groupSpaces + wordWrap(formattedMessage, {
1417
+ trim: false,
1418
+ width: size - 3,
1419
+ wrapMode: WrapMode.STRICT_WIDTH
1420
+ })
1421
+ );
1422
+ }
1423
+ if (context) {
1424
+ let hasError = false;
1425
+ items.push(
1426
+ ...context.map((value) => {
1427
+ if (value instanceof Error) {
1428
+ hasError = true;
1429
+ return `
1430
+
1431
+ ${renderError(value, {
1432
+ ...this.#errorOptions,
1433
+ filterStacktrace: pailFileFilter,
1434
+ prefix: groupSpaces
1435
+ })}`;
1436
+ }
1437
+ if (typeof value === "object") {
1438
+ return ` ${inspect(value, this.#inspectOptions)}`;
1439
+ }
1440
+ const newValue = (hasError ? "\n\n" : " ") + String(value);
1441
+ hasError = false;
1442
+ return newValue;
1443
+ })
1444
+ );
1445
+ }
1446
+ if (error) {
1447
+ items.push(
1448
+ renderError(error, {
1449
+ ...this.#errorOptions,
1450
+ filterStacktrace: pailFileFilter,
1451
+ prefix: groupSpaces
1452
+ })
1453
+ );
1454
+ }
1455
+ if (traceError) {
1456
+ items.push(
1457
+ `
1458
+
1459
+ ${renderError(traceError, {
1460
+ ...this.#errorOptions,
1461
+ filterStacktrace: pailFileFilter,
1462
+ hideErrorCauseCodeView: true,
1463
+ hideErrorCodeView: true,
1464
+ hideErrorErrorsCodeView: true,
1465
+ hideMessage: true,
1466
+ prefix: groupSpaces
1467
+ })}`
1468
+ );
1469
+ }
1470
+ if (suffix) {
1471
+ items.push("\n", groupSpaces + grey(this.styles.underline.suffix ? underline(suffix) : suffix));
1472
+ }
1473
+ return items.join("");
1474
+ }
1475
+ // eslint-disable-next-line no-underscore-dangle
1476
+ _log(message, logLevel) {
1477
+ const streamType = ["error", "trace", "warn"].includes(logLevel) ? "stderr" : "stdout";
1478
+ const stream = streamType === "stderr" ? this.#stderr : this.#stdout;
1479
+ if (this.#interactive && this.#interactiveManager !== void 0 && stream.isTTY) {
1480
+ this.#interactiveManager.update(streamType, message.split("\n"), 0);
1481
+ } else {
1482
+ writeStream(`${message}
1483
+ `, stream);
1484
+ }
1485
+ }
1486
+ }
1487
+
1488
+ export { PrettyReporter };