UNPKG

2.25 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const arraySum = array => {
9 let sum = 0;
10 for (const item of array) sum += item;
11 return sum;
12};
13
14/**
15 * @param {any[]} args items to be truncated
16 * @param {number} maxLength maximum length of args including spaces between
17 * @returns {string[]} truncated args
18 */
19const truncateArgs = (args, maxLength) => {
20 const lengths = args.map(a => `${a}`.length);
21 const availableLength = maxLength - lengths.length + 1;
22
23 if (availableLength > 0 && args.length === 1) {
24 if (availableLength >= args[0].length) {
25 return args;
26 } else if (availableLength > 3) {
27 return ["..." + args[0].slice(-availableLength + 3)];
28 } else {
29 return [args[0].slice(-availableLength)];
30 }
31 }
32
33 // Check if there is space for at least 4 chars per arg
34 if (availableLength < arraySum(lengths.map(i => Math.min(i, 6)))) {
35 // remove args
36 if (args.length > 1)
37 return truncateArgs(args.slice(0, args.length - 1), maxLength);
38 return [];
39 }
40
41 let currentLength = arraySum(lengths);
42
43 // Check if all fits into maxLength
44 if (currentLength <= availableLength) return args;
45
46 // Try to remove chars from the longest items until it fits
47 while (currentLength > availableLength) {
48 const maxLength = Math.max(...lengths);
49 const shorterItems = lengths.filter(l => l !== maxLength);
50 const nextToMaxLength =
51 shorterItems.length > 0 ? Math.max(...shorterItems) : 0;
52 const maxReduce = maxLength - nextToMaxLength;
53 let maxItems = lengths.length - shorterItems.length;
54 let overrun = currentLength - availableLength;
55 for (let i = 0; i < lengths.length; i++) {
56 if (lengths[i] === maxLength) {
57 const reduce = Math.min(Math.floor(overrun / maxItems), maxReduce);
58 lengths[i] -= reduce;
59 currentLength -= reduce;
60 overrun -= reduce;
61 maxItems--;
62 }
63 }
64 }
65
66 // Return args reduced to length in lengths
67 return args.map((a, i) => {
68 const str = `${a}`;
69 const length = lengths[i];
70 if (str.length === length) {
71 return str;
72 } else if (length > 5) {
73 return "..." + str.slice(-length + 3);
74 } else if (length > 0) {
75 return str.slice(-length);
76 } else {
77 return "";
78 }
79 });
80};
81
82module.exports = truncateArgs;