11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci ArrayPrototypeJoin, 51cb0ef41Sopenharmony_ci ArrayPrototypeMap, 61cb0ef41Sopenharmony_ci MathCeil, 71cb0ef41Sopenharmony_ci MathMax, 81cb0ef41Sopenharmony_ci MathMaxApply, 91cb0ef41Sopenharmony_ci ObjectPrototypeHasOwnProperty, 101cb0ef41Sopenharmony_ci StringPrototypeRepeat, 111cb0ef41Sopenharmony_ci} = primordials; 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciconst { getStringWidth } = require('internal/util/inspect'); 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci// The use of Unicode characters below is the only non-comment use of non-ASCII 161cb0ef41Sopenharmony_ci// Unicode characters in Node.js built-in modules. If they are ever removed or 171cb0ef41Sopenharmony_ci// rewritten with \u escapes, then a test will need to be (re-)added to Node.js 181cb0ef41Sopenharmony_ci// core to verify that Unicode characters work in built-ins. 191cb0ef41Sopenharmony_ci// Refs: https://github.com/nodejs/node/issues/10673 201cb0ef41Sopenharmony_ciconst tableChars = { 211cb0ef41Sopenharmony_ci /* eslint-disable node-core/non-ascii-character */ 221cb0ef41Sopenharmony_ci middleMiddle: '─', 231cb0ef41Sopenharmony_ci rowMiddle: '┼', 241cb0ef41Sopenharmony_ci topRight: '┐', 251cb0ef41Sopenharmony_ci topLeft: '┌', 261cb0ef41Sopenharmony_ci leftMiddle: '├', 271cb0ef41Sopenharmony_ci topMiddle: '┬', 281cb0ef41Sopenharmony_ci bottomRight: '┘', 291cb0ef41Sopenharmony_ci bottomLeft: '└', 301cb0ef41Sopenharmony_ci bottomMiddle: '┴', 311cb0ef41Sopenharmony_ci rightMiddle: '┤', 321cb0ef41Sopenharmony_ci left: '│ ', 331cb0ef41Sopenharmony_ci right: ' │', 341cb0ef41Sopenharmony_ci middle: ' │ ', 351cb0ef41Sopenharmony_ci /* eslint-enable node-core/non-ascii-character */ 361cb0ef41Sopenharmony_ci}; 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ciconst renderRow = (row, columnWidths) => { 391cb0ef41Sopenharmony_ci let out = tableChars.left; 401cb0ef41Sopenharmony_ci for (let i = 0; i < row.length; i++) { 411cb0ef41Sopenharmony_ci const cell = row[i]; 421cb0ef41Sopenharmony_ci const len = getStringWidth(cell); 431cb0ef41Sopenharmony_ci const needed = (columnWidths[i] - len) / 2; 441cb0ef41Sopenharmony_ci // round(needed) + ceil(needed) will always add up to the amount 451cb0ef41Sopenharmony_ci // of spaces we need while also left justifying the output. 461cb0ef41Sopenharmony_ci out += StringPrototypeRepeat(' ', needed) + cell + 471cb0ef41Sopenharmony_ci StringPrototypeRepeat(' ', MathCeil(needed)); 481cb0ef41Sopenharmony_ci if (i !== row.length - 1) 491cb0ef41Sopenharmony_ci out += tableChars.middle; 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci out += tableChars.right; 521cb0ef41Sopenharmony_ci return out; 531cb0ef41Sopenharmony_ci}; 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ciconst table = (head, columns) => { 561cb0ef41Sopenharmony_ci const rows = []; 571cb0ef41Sopenharmony_ci const columnWidths = ArrayPrototypeMap(head, (h) => getStringWidth(h)); 581cb0ef41Sopenharmony_ci const longestColumn = MathMaxApply(ArrayPrototypeMap(columns, (a) => 591cb0ef41Sopenharmony_ci a.length)); 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci for (let i = 0; i < head.length; i++) { 621cb0ef41Sopenharmony_ci const column = columns[i]; 631cb0ef41Sopenharmony_ci for (let j = 0; j < longestColumn; j++) { 641cb0ef41Sopenharmony_ci if (rows[j] === undefined) 651cb0ef41Sopenharmony_ci rows[j] = []; 661cb0ef41Sopenharmony_ci const value = rows[j][i] = 671cb0ef41Sopenharmony_ci ObjectPrototypeHasOwnProperty(column, j) ? column[j] : ''; 681cb0ef41Sopenharmony_ci const width = columnWidths[i] || 0; 691cb0ef41Sopenharmony_ci const counted = getStringWidth(value); 701cb0ef41Sopenharmony_ci columnWidths[i] = MathMax(width, counted); 711cb0ef41Sopenharmony_ci } 721cb0ef41Sopenharmony_ci } 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci const divider = ArrayPrototypeMap(columnWidths, (i) => 751cb0ef41Sopenharmony_ci StringPrototypeRepeat(tableChars.middleMiddle, i + 2)); 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci let result = tableChars.topLeft + 781cb0ef41Sopenharmony_ci ArrayPrototypeJoin(divider, tableChars.topMiddle) + 791cb0ef41Sopenharmony_ci tableChars.topRight + '\n' + 801cb0ef41Sopenharmony_ci renderRow(head, columnWidths) + '\n' + 811cb0ef41Sopenharmony_ci tableChars.leftMiddle + 821cb0ef41Sopenharmony_ci ArrayPrototypeJoin(divider, tableChars.rowMiddle) + 831cb0ef41Sopenharmony_ci tableChars.rightMiddle + '\n'; 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci for (const row of rows) 861cb0ef41Sopenharmony_ci result += `${renderRow(row, columnWidths)}\n`; 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci result += tableChars.bottomLeft + 891cb0ef41Sopenharmony_ci ArrayPrototypeJoin(divider, tableChars.bottomMiddle) + 901cb0ef41Sopenharmony_ci tableChars.bottomRight; 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci return result; 931cb0ef41Sopenharmony_ci}; 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_cimodule.exports = table; 96