mirror of
https://github.com/nodejs/node.git
synced 2025-05-06 05:21:19 +00:00

Store all primordials as properties of the primordials object. Static functions are prefixed by the constructor's name and prototype methods are prefixed by the constructor's name followed by "Prototype". For example: primordials.Object.keys becomes primordials.ObjectKeys. PR-URL: https://github.com/nodejs/node/pull/30610 Refs: https://github.com/nodejs/node/issues/29766 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
87 lines
2.7 KiB
JavaScript
87 lines
2.7 KiB
JavaScript
'use strict';
|
|
|
|
const {
|
|
MathCeil,
|
|
MathMax,
|
|
ObjectPrototypeHasOwnProperty,
|
|
} = primordials;
|
|
|
|
const { getStringWidth } = require('internal/readline/utils');
|
|
|
|
// The use of Unicode characters below is the only non-comment use of non-ASCII
|
|
// Unicode characters in Node.js built-in modules. If they are ever removed or
|
|
// rewritten with \u escapes, then a test will need to be (re-)added to Node.js
|
|
// core to verify that Unicode characters work in built-ins. Otherwise,
|
|
// consumers using Unicode in _third_party_main.js will run into problems.
|
|
// Refs: https://github.com/nodejs/node/issues/10673
|
|
const tableChars = {
|
|
/* eslint-disable node-core/non-ascii-character */
|
|
middleMiddle: '─',
|
|
rowMiddle: '┼',
|
|
topRight: '┐',
|
|
topLeft: '┌',
|
|
leftMiddle: '├',
|
|
topMiddle: '┬',
|
|
bottomRight: '┘',
|
|
bottomLeft: '└',
|
|
bottomMiddle: '┴',
|
|
rightMiddle: '┤',
|
|
left: '│ ',
|
|
right: ' │',
|
|
middle: ' │ ',
|
|
/* eslint-enable node-core/non-ascii-character */
|
|
};
|
|
|
|
const renderRow = (row, columnWidths) => {
|
|
let out = tableChars.left;
|
|
for (let i = 0; i < row.length; i++) {
|
|
const cell = row[i];
|
|
const len = getStringWidth(cell);
|
|
const needed = (columnWidths[i] - len) / 2;
|
|
// round(needed) + ceil(needed) will always add up to the amount
|
|
// of spaces we need while also left justifying the output.
|
|
out += `${' '.repeat(needed)}${cell}${' '.repeat(MathCeil(needed))}`;
|
|
if (i !== row.length - 1)
|
|
out += tableChars.middle;
|
|
}
|
|
out += tableChars.right;
|
|
return out;
|
|
};
|
|
|
|
const table = (head, columns) => {
|
|
const rows = [];
|
|
const columnWidths = head.map((h) => getStringWidth(h));
|
|
const longestColumn = columns.reduce((n, a) => MathMax(n, a.length), 0);
|
|
|
|
for (let i = 0; i < head.length; i++) {
|
|
const column = columns[i];
|
|
for (let j = 0; j < longestColumn; j++) {
|
|
if (rows[j] === undefined)
|
|
rows[j] = [];
|
|
const value = rows[j][i] =
|
|
ObjectPrototypeHasOwnProperty(column, j) ? column[j] : '';
|
|
const width = columnWidths[i] || 0;
|
|
const counted = getStringWidth(value);
|
|
columnWidths[i] = MathMax(width, counted);
|
|
}
|
|
}
|
|
|
|
const divider = columnWidths.map((i) =>
|
|
tableChars.middleMiddle.repeat(i + 2));
|
|
|
|
let result = `${tableChars.topLeft}${divider.join(tableChars.topMiddle)}` +
|
|
`${tableChars.topRight}\n${renderRow(head, columnWidths)}\n` +
|
|
`${tableChars.leftMiddle}${divider.join(tableChars.rowMiddle)}` +
|
|
`${tableChars.rightMiddle}\n`;
|
|
|
|
for (const row of rows)
|
|
result += `${renderRow(row, columnWidths)}\n`;
|
|
|
|
result += `${tableChars.bottomLeft}${divider.join(tableChars.bottomMiddle)}` +
|
|
tableChars.bottomRight;
|
|
|
|
return result;
|
|
};
|
|
|
|
module.exports = table;
|