@andrew_l/pino-pretty 0.2.17 → 0.2.18

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.
package/dist/index.d.cts CHANGED
@@ -91,6 +91,11 @@ type TypeConfig = {
91
91
  color: ColorValue;
92
92
  };
93
93
  interface PrettyOptions {
94
+ /**
95
+ * Pino message key.
96
+ * @default 'regular'
97
+ */
98
+ inspect: 'regular' | 'compact' | InspectFunction;
94
99
  /**
95
100
  * Pino message key.
96
101
  */
@@ -168,6 +173,26 @@ type TypeName = 'number' | 'boolean' | 'string' | 'object' | 'error' | 'errorSta
168
173
  * Can be a single color name, array of color names, or 'rand' for random colors.
169
174
  */
170
175
  type ColorValue = 'rand' | Arrayable<ColorName>;
176
+ type InspectFunction = (obj: any, opts: InspectOptions) => string;
177
+ interface InspectOptions {
178
+ /** Maximum depth of the inspection @default 5 */
179
+ depth: number;
180
+ /** Quote style for strings @default 'single' */
181
+ quoteStyle: 'single' | 'double';
182
+ /** Maximum string length before truncation @default Infinity */
183
+ maxStringLength: number;
184
+ /** Indentation spaces @default 2 */
185
+ indent: number;
186
+ /** Add numeric separators (1_234.567_8) @default false */
187
+ numericSeparator: boolean;
188
+ /** Custom stringify functions for different types */
189
+ customStringify: {
190
+ [x: string]: InspectCustomStringify;
191
+ };
192
+ /** Available width columns */
193
+ columns: number;
194
+ }
195
+ type InspectCustomStringify = (value: any) => string;
171
196
 
172
197
  declare namespace PinoPretty {
173
198
  type Options = DeepPartial<PrettyOptions>;
package/dist/index.d.mts CHANGED
@@ -91,6 +91,11 @@ type TypeConfig = {
91
91
  color: ColorValue;
92
92
  };
93
93
  interface PrettyOptions {
94
+ /**
95
+ * Pino message key.
96
+ * @default 'regular'
97
+ */
98
+ inspect: 'regular' | 'compact' | InspectFunction;
94
99
  /**
95
100
  * Pino message key.
96
101
  */
@@ -168,6 +173,26 @@ type TypeName = 'number' | 'boolean' | 'string' | 'object' | 'error' | 'errorSta
168
173
  * Can be a single color name, array of color names, or 'rand' for random colors.
169
174
  */
170
175
  type ColorValue = 'rand' | Arrayable<ColorName>;
176
+ type InspectFunction = (obj: any, opts: InspectOptions) => string;
177
+ interface InspectOptions {
178
+ /** Maximum depth of the inspection @default 5 */
179
+ depth: number;
180
+ /** Quote style for strings @default 'single' */
181
+ quoteStyle: 'single' | 'double';
182
+ /** Maximum string length before truncation @default Infinity */
183
+ maxStringLength: number;
184
+ /** Indentation spaces @default 2 */
185
+ indent: number;
186
+ /** Add numeric separators (1_234.567_8) @default false */
187
+ numericSeparator: boolean;
188
+ /** Custom stringify functions for different types */
189
+ customStringify: {
190
+ [x: string]: InspectCustomStringify;
191
+ };
192
+ /** Available width columns */
193
+ columns: number;
194
+ }
195
+ type InspectCustomStringify = (value: any) => string;
171
196
 
172
197
  declare namespace PinoPretty {
173
198
  type Options = DeepPartial<PrettyOptions>;
package/dist/index.d.ts CHANGED
@@ -91,6 +91,11 @@ type TypeConfig = {
91
91
  color: ColorValue;
92
92
  };
93
93
  interface PrettyOptions {
94
+ /**
95
+ * Pino message key.
96
+ * @default 'regular'
97
+ */
98
+ inspect: 'regular' | 'compact' | InspectFunction;
94
99
  /**
95
100
  * Pino message key.
96
101
  */
@@ -168,6 +173,26 @@ type TypeName = 'number' | 'boolean' | 'string' | 'object' | 'error' | 'errorSta
168
173
  * Can be a single color name, array of color names, or 'rand' for random colors.
169
174
  */
170
175
  type ColorValue = 'rand' | Arrayable<ColorName>;
176
+ type InspectFunction = (obj: any, opts: InspectOptions) => string;
177
+ interface InspectOptions {
178
+ /** Maximum depth of the inspection @default 5 */
179
+ depth: number;
180
+ /** Quote style for strings @default 'single' */
181
+ quoteStyle: 'single' | 'double';
182
+ /** Maximum string length before truncation @default Infinity */
183
+ maxStringLength: number;
184
+ /** Indentation spaces @default 2 */
185
+ indent: number;
186
+ /** Add numeric separators (1_234.567_8) @default false */
187
+ numericSeparator: boolean;
188
+ /** Custom stringify functions for different types */
189
+ customStringify: {
190
+ [x: string]: InspectCustomStringify;
191
+ };
192
+ /** Available width columns */
193
+ columns: number;
194
+ }
195
+ type InspectCustomStringify = (value: any) => string;
171
196
 
172
197
  declare namespace PinoPretty {
173
198
  type Options = DeepPartial<PrettyOptions>;
package/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import { Transform } from 'node:stream';
2
2
  import abstractTransport from 'pino-abstract-transport';
3
3
  import pump from 'pump';
4
- import { noop, isObject, isFunction, withCache, crc32, deepDefaults, arrayable, capitalize, isString, omit, has } from '@andrew_l/toolkit';
4
+ import { noop, isObject, isFunction, typeOf, isPrimitive, withCache, crc32, deepDefaults, arrayable, capitalize, isString, omit, def, has } from '@andrew_l/toolkit';
5
5
  import path from 'node:path';
6
- import { inspect as inspect$1, formatWithOptions } from 'node:util';
6
+ import { inspect, formatWithOptions } from 'node:util';
7
7
  import _SonicBoom from 'sonic-boom';
8
8
  import { isMainThread } from 'node:worker_threads';
9
9
  import * as tty from 'node:tty';
@@ -196,24 +196,36 @@ function addNumericSeparator(num, str) {
196
196
  }
197
197
  return str.replace(SEP_REGEX, "$&_");
198
198
  }
199
- function inspectString(str, opts) {
200
- var processedStr = str;
201
- if (str.length > opts.maxStringLength) {
202
- var remaining = str.length - opts.maxStringLength;
203
- var trailer = `... ${remaining} more character${remaining > 1 ? "s" : ""}`;
204
- processedStr = str.slice(0, opts.maxStringLength);
205
- return inspectString(processedStr, opts) + trailer;
206
- }
199
+ function escapeString(str, opts) {
207
200
  var quoteRegex = QUOTE_REGEX[opts.quoteStyle];
208
- var escaped = processedStr.replace(quoteRegex, "\\$1").replace(/[\x00-\x1f]/g, (char) => {
201
+ return str.replace(quoteRegex, "\\$1").replace(/[\x00-\x1f]/g, (char) => {
209
202
  var code = char.charCodeAt(0);
210
203
  var escapeChar = ESCAPE_CHARS[code];
211
204
  return escapeChar ? `\\${escapeChar}` : `\\x${code.toString(16).padStart(2, "0").toUpperCase()}`;
212
205
  });
206
+ }
207
+ function inspectString$1(str, opts) {
208
+ if (str.length > opts.maxStringLength) {
209
+ var remaining = str.length - opts.maxStringLength;
210
+ var trailer = `... ${remaining} more character${remaining > 1 ? "s" : ""}`;
211
+ str = str.slice(0, opts.maxStringLength);
212
+ return inspectString$1(str, opts) + trailer;
213
+ }
214
+ var escaped = escapeString(str, opts);
213
215
  var quote = QUOTES[opts.quoteStyle];
214
216
  var result = `${quote}${escaped}${quote}`;
215
217
  return opts.customStringify.string?.(result) ?? result;
216
218
  }
219
+ function inspectNumber(num, opts) {
220
+ if (typeof num === "bigint") {
221
+ var str = `${num}n`;
222
+ var result = opts.numericSeparator ? addNumericSeparator(num, str) : str;
223
+ return opts.customStringify.number?.(result) ?? result;
224
+ }
225
+ var str = Object.is(num, -0) ? "-0" : String(num);
226
+ var result = opts.numericSeparator ? addNumericSeparator(num, str) : str;
227
+ return opts.customStringify.number?.(result) ?? result;
228
+ }
217
229
  function getIndentStrings(opts, depth) {
218
230
  if (depth === 0) return { base: " ".repeat(opts.indent), prev: "" };
219
231
  return {
@@ -248,23 +260,17 @@ function getObjectEntries(obj, inspectFn) {
248
260
  }
249
261
  return entries;
250
262
  }
251
- function inspectValue(obj, opts, depth, seen) {
263
+ function inspectValue$1(obj, opts, depth, seen) {
252
264
  if (obj === void 0)
253
265
  return opts.customStringify.undefined?.(obj) ?? "undefined";
254
266
  if (obj === null) return opts.customStringify.null?.(obj) ?? "null";
255
267
  if (typeof obj === "boolean")
256
268
  return opts.customStringify.boolean?.(obj) ?? String(obj);
257
- if (typeof obj === "string") return inspectString(obj, opts);
269
+ if (typeof obj === "string") return inspectString$1(obj, opts);
258
270
  if (typeof obj === "number") {
259
- if (obj === 0) return Object.is(obj, -0) ? "-0" : "0";
260
- var str = String(obj);
261
- var result = opts.numericSeparator ? addNumericSeparator(obj, str) : str;
262
- return opts.customStringify.number?.(result) ?? result;
263
- }
264
- if (typeof obj === "bigint") {
265
- var str = `${obj}n`;
266
- var result = opts.numericSeparator ? addNumericSeparator(obj, str) : str;
267
- return opts.customStringify.number?.(result) ?? result;
271
+ return inspectNumber(obj, opts);
272
+ } else if (typeof obj === "bigint") {
273
+ return inspectNumber(obj, opts);
268
274
  }
269
275
  if (depth >= opts.depth && opts.depth > 0 && typeof obj === "object") {
270
276
  return Array.isArray(obj) ? "[Array]" : "[Object]";
@@ -272,7 +278,7 @@ function inspectValue(obj, opts, depth, seen) {
272
278
  if (seen.has(obj)) return "[Circular]";
273
279
  seen.add(obj);
274
280
  var indent = getIndentStrings(opts, depth);
275
- var inspectChild = (value) => inspectValue(value, opts, depth + 1, seen);
281
+ var inspectChild = (value) => inspectValue$1(value, opts, depth + 1, seen);
276
282
  if (Array.isArray(obj)) {
277
283
  if (obj.length === 0) return "[]";
278
284
  var entries = getObjectEntries(obj, inspectChild);
@@ -282,10 +288,10 @@ function inspectValue(obj, opts, depth, seen) {
282
288
  return `[ ${entries.join(", ")} ]`;
283
289
  }
284
290
  if (isObject(obj)) {
285
- if (isFunction(obj[inspect$1.custom])) {
291
+ if (isFunction(obj[inspect.custom])) {
286
292
  var lineJoiner = `
287
293
  ${indent.prev}`;
288
- return inspect$1(obj, { depth: opts.depth - depth }).split("\n").join(lineJoiner);
294
+ return inspect(obj, { depth: opts.depth - depth }).split("\n").join(lineJoiner);
289
295
  }
290
296
  var entries = getObjectEntries(obj, inspectChild);
291
297
  if (entries.length === 0) return "{}";
@@ -297,9 +303,137 @@ ${indent.prev}`;
297
303
  seen.delete(obj);
298
304
  return String(obj);
299
305
  }
300
- function inspect(obj, options) {
306
+ function inspectRegular(obj, options) {
307
+ return inspectValue$1(obj, options, 0, /* @__PURE__ */ new WeakSet());
308
+ }
309
+
310
+ var INSPECT_MAP = {
311
+ boolean: (obj, opts) => opts.customStringify.boolean?.(obj) ?? String(obj),
312
+ string: inspectString,
313
+ number: inspectNumber,
314
+ bigint: inspectNumber,
315
+ undefined: (obj, opts) => opts.customStringify.undefined?.(obj) ?? "undefined",
316
+ null: () => "null",
317
+ array: formatArray,
318
+ object: formatObject
319
+ };
320
+ function inspectCompact(obj, options) {
301
321
  return inspectValue(obj, options, 0, /* @__PURE__ */ new WeakSet());
302
322
  }
323
+ function inspectValue(obj, opts, depth = 0, seen) {
324
+ var spaces = depth > 0 ? " ".repeat(opts.indent * depth) : "";
325
+ var type = typeOf(obj);
326
+ var inspectFn = INSPECT_MAP[type] || String;
327
+ if (isFunction(obj[inspect.custom])) {
328
+ var lineJoiner = `
329
+ ${spaces}`;
330
+ return spaces + inspect(obj, { depth: opts.depth - depth }).split("\n").join(lineJoiner);
331
+ }
332
+ return inspectFn(obj, opts, depth, spaces, seen);
333
+ }
334
+ function inspectString(str, opts) {
335
+ if (str.length > opts.maxStringLength) {
336
+ var remaining = str.length - opts.maxStringLength;
337
+ str = str.slice(0, opts.maxStringLength);
338
+ return formatString(str, remaining, opts);
339
+ }
340
+ return formatString(str, 0, opts);
341
+ }
342
+ function formatString(str, remaining, opts) {
343
+ var escaped = escapeString(str, opts);
344
+ var quote = QUOTES[opts.quoteStyle];
345
+ var result;
346
+ var trailer = remaining > 0 ? opts.customStringify.stringRemaining(`... ${remaining} more characters`) : "";
347
+ if (escaped.length > opts.columns && escaped.includes("\\n")) {
348
+ escaped = escaped.replaceAll("\\n", "\n");
349
+ result = "\n```\n" + (trailer ? `${escaped}
350
+ ${trailer}` : escaped) + "\n```";
351
+ } else {
352
+ result = `${quote}${escaped}${trailer ?? ""}${quote}`;
353
+ }
354
+ return opts.customStringify.string?.(result) ?? result;
355
+ }
356
+ function formatArray(arr, opts, depth, spaces, seen) {
357
+ if (opts.depth > 0 && depth >= opts.depth) {
358
+ return "[Array]";
359
+ }
360
+ if (seen.has(arr)) {
361
+ return "[Circular]";
362
+ }
363
+ seen.add(arr);
364
+ var len = arr.length;
365
+ if (isCompactFormat(arr, depth, spaces.length, opts)) {
366
+ var compact = [];
367
+ for (var i = 0; i < len; i++) {
368
+ compact.push(inspectValue(arr[i], opts, 0, seen));
369
+ }
370
+ return `[${compact.join(", ")}]`;
371
+ }
372
+ var multiline = [];
373
+ for (var i = 0; i < len; i++) {
374
+ var strValue = inspectValue(arr[i], opts, depth + 1, seen);
375
+ multiline.push(
376
+ `${spaces}- ${strValue.trimStart ? strValue.trimStart() : strValue}`
377
+ );
378
+ }
379
+ return multiline.join("\n");
380
+ }
381
+ function isCompactFormat(value, depth, spaces, opts) {
382
+ var availableLength = opts.columns - spaces - depth * opts.indent;
383
+ var totalLength = 0;
384
+ if (availableLength <= 0) return false;
385
+ for (var item of value.flat()) {
386
+ totalLength += String(item).length + 2;
387
+ if (totalLength > availableLength || !isPrimitive(item)) return false;
388
+ }
389
+ return true;
390
+ }
391
+ function formatObject(obj, opts, depth, spaces, seen) {
392
+ if (opts.depth > 0 && depth >= opts.depth) {
393
+ return "[Array]";
394
+ }
395
+ if (seen.has(obj)) {
396
+ return "[Circular]";
397
+ }
398
+ seen.add(obj);
399
+ var entries = Object.entries(obj);
400
+ var len = entries.length;
401
+ if (len === 0) return "{}";
402
+ if (isCompactFormat(entries, depth, spaces.length, opts)) {
403
+ var compact = [];
404
+ var key, value;
405
+ for (var i = 0; i < len; i++) {
406
+ key = entries[i][0];
407
+ value = entries[i][1];
408
+ compact.push(`${key}: ${inspectValue(value, opts, 0, seen)}`);
409
+ }
410
+ return `{ ${compact.join(", ")} }`;
411
+ }
412
+ var multiline = [];
413
+ var key, value, strValue, compactMode;
414
+ for (var i = 0; i < len; i++) {
415
+ key = entries[i][0];
416
+ value = entries[i][1];
417
+ strValue = inspectValue(value, opts, depth + 1, seen);
418
+ compactMode = strValue[0] === "{" || strValue[0] === "[";
419
+ if (compactMode) {
420
+ multiline.push(`${spaces}${key}: ${strValue}`);
421
+ } else if (value && typeof value === "object") {
422
+ if (Array.isArray(value) && value.length > 0 && strValue[0] !== "[") {
423
+ multiline.push(`${spaces}${key}:
424
+ ${strValue}`);
425
+ } else if (!Array.isArray(value)) {
426
+ multiline.push(`${spaces}${key}:
427
+ ${strValue}`);
428
+ } else {
429
+ multiline.push(`${spaces}${key}: ${strValue}`);
430
+ }
431
+ } else {
432
+ multiline.push(`${spaces}${key}: ${strValue}`);
433
+ }
434
+ }
435
+ return multiline.join("\n");
436
+ }
303
437
 
304
438
  function parseOptions(value) {
305
439
  const defOptions = {
@@ -313,6 +447,7 @@ function parseOptions(value) {
313
447
  numericSeparator: false,
314
448
  ignore: "hostname,pid",
315
449
  colorize: true,
450
+ inspect: "compact",
316
451
  types: {
317
452
  number: { color: "green" },
318
453
  boolean: { color: "redBright" },
@@ -342,13 +477,15 @@ function parseOptions(value) {
342
477
  ...opts,
343
478
  sw,
344
479
  colorFallback: createColorizeFn(opts.colorize, "gray"),
345
- inspect: {
480
+ inspectFn: opts.inspect === "regular" ? inspectRegular : opts.inspect === "compact" ? inspectCompact : isFunction(opts.inspect) ? opts.inspect : inspectRegular,
481
+ inspectOptions: {
346
482
  depth: opts.depth,
347
483
  quoteStyle: opts.quoteStyle,
348
484
  indent: opts.indent,
349
485
  maxStringLength: opts.maxStringLength,
350
486
  numericSeparator: opts.numericSeparator,
351
- customStringify: {}
487
+ customStringify: {},
488
+ columns: opts.columns
352
489
  },
353
490
  levels: Object.fromEntries(
354
491
  Object.entries(opts.levels).map(([key, value2]) => [
@@ -382,10 +519,11 @@ function parseOptions(value) {
382
519
  opts.ignore.split(",").map((v) => v.trim()).filter(Boolean)
383
520
  )
384
521
  };
385
- result.inspect.customStringify = {
522
+ result.inspectOptions.customStringify = {
386
523
  number: result.types.number.color,
387
524
  boolean: result.types.boolean.color,
388
- string: result.types.string.color
525
+ string: result.types.string.color,
526
+ stringRemaining: result.colorFallback
389
527
  };
390
528
  return result;
391
529
  }
@@ -488,20 +626,16 @@ function formatAdditional(obj, opts) {
488
626
  for (const key in obj) {
489
627
  empty = false;
490
628
  if (isSerializedError(obj[key])) {
491
- additional[key] = {
492
- ...obj[key],
493
- [inspect$1.custom]: () => formatError(obj[key], 0, opts)
494
- };
495
- } else {
496
- additional[key] = obj[key];
629
+ def(obj[key], inspect.custom, () => formatError(obj[key], 0, opts));
497
630
  }
631
+ additional[key] = obj[key];
498
632
  }
499
633
  }
500
634
  if (empty) {
501
635
  return "";
502
636
  }
503
637
  const colorizeObject = opts.types.object?.color || opts.colorFallback;
504
- return colorizeObject(inspect(additional, opts.inspect).slice(2, -2));
638
+ return colorizeObject(opts.inspectFn(additional, opts.inspectOptions));
505
639
  }
506
640
  function pretty(logObj) {
507
641
  const opts = this;
@@ -535,12 +669,22 @@ function build(opts = {}) {
535
669
  messageKey: source.messageKey || "msg",
536
670
  ...opts
537
671
  });
672
+ var extraLine = false;
673
+ var line;
538
674
  const stream = new Transform({
539
675
  objectMode: true,
540
676
  autoDestroy: true,
541
677
  transform(chunk, enc, cb) {
542
- const line = pretty2(chunk);
543
- cb(null, line + "\n");
678
+ line = pretty2(chunk);
679
+ if (line.endsWith("\n")) {
680
+ extraLine = true;
681
+ } else if (extraLine) {
682
+ line = "\n" + line + "\n";
683
+ extraLine = false;
684
+ } else {
685
+ line = line + "\n";
686
+ }
687
+ cb(null, line);
544
688
  }
545
689
  });
546
690
  destination = buildSafeSonicBoom({
@@ -549,8 +693,8 @@ function build(opts = {}) {
549
693
  mkdir: true,
550
694
  sync: false
551
695
  });
552
- source.on("unknown", function(line) {
553
- destination.write(line + "\n");
696
+ source.on("unknown", function(line2) {
697
+ destination.write(line2 + "\n");
554
698
  });
555
699
  pump(source, stream, destination);
556
700
  return stream;