UNPKG

takin

Version:

Front end engineering base toolchain and scaffold

294 lines 12 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConsoleCliTable = void 0; const chalk_1 = __importDefault(require("chalk")); const lodash_1 = require("lodash"); const wcwidth_1 = __importDefault(require("wcwidth")); const colorModifierSupport_1 = require("../utils/colorModifierSupport"); /** * 用于生成终端表格 */ class ConsoleCliTable extends Array { constructor(options) { super(); this.options = this.mergeOptions({ // prettier-ignore chars: { 'middle': '│', 'left': '│', 'right': '│', 'top-left': '┌', 'top-mid': '┬', 'top': '─', 'top-right': '┐', 'left-mid': '├', 'mid-mid': '┼', 'mid': '─', 'right-mid': '┤', 'bottom-left': '└', 'bottom-mid': '┴', 'bottom': '─', 'bottom-right': '┘', }, truncate: '…', colWidths: [], colAligns: [], style: { 'padding-left': 1, 'padding-right': 1, head: (0, colorModifierSupport_1.isSupportColorModifier)() ? ['bold', 'cyan'] : ['cyan'], border: ['cyan'], compact: false }, head: [] }, options || {}); if (options && options.rows) { for (let i = 0; i < options.rows.length; i++) { this.push(options.rows[i]); } } } mergeOptions(defaults, opts) { for (const p in opts) { if (p === '__proto__' || p === 'constructor' || p === 'prototype') { continue; } if (opts[p] && opts[p].constructor && opts[p].constructor === Object) { defaults[p] = defaults[p] || {}; this.mergeOptions(defaults[p], opts[p]); } else { defaults[p] = opts[p]; } } return defaults; } get width() { const str = this.toString().split('\n'); if (str.length) return str[0].length; return 0; } /** * For consideration of terminal "color" programs like colors.js, * which can add ANSI escape color codes to strings, * we destyle the ANSI color escape codes for padding calculations. * * see: http://en.wikipedia.org/wiki/ANSI_escape_code */ strlen(str) { // eslint-disable-next-line no-control-regex const code = /\u001b\[(?:\d*;){0,5}\d*m/g; const stripped = ('' + str).replace(code, ''); const split = stripped.split('\n'); return split.reduce(function (memo, s) { const len = (0, wcwidth_1.default)(s); return len > memo ? len : memo; // return s.length > memo ? s.length : memo }, 0); } render() { let ret = ''; const options = this.options; const style = options.style || {}; const head = options.head || []; const chars = options.chars || {}; const truncater = options.truncate; const colWidths = options.colWidths || new Array(head.length); let totalWidth = 0; const getWidth = (obj) => { return typeof obj === 'object' && obj.width !== undefined ? obj.width : (typeof obj === 'object' ? this.strlen(obj.text) : this.strlen(obj)) + (style['padding-left'] || 0) + (style['padding-right'] || 0); }; // renders a string, by padding it or truncating it const renderString = (str, index) => { var _a; str = String(typeof str === 'object' && str.text ? str.text : str); const length = this.strlen(str); const width = colWidths[index] - (style['padding-left'] || 0) - (style['padding-right'] || 0); const align = ((_a = options.colAligns) === null || _a === void 0 ? void 0 : _a[index]) || 'left'; const padFn = align === 'left' ? lodash_1.padEnd : align === 'middle' ? lodash_1.pad : lodash_1.padStart; return ((0, lodash_1.repeat)(' ', style['padding-left'] || 0) + (length === width ? str : length < width ? padFn(str, width + (str.length - length), ' ') : truncater ? (0, lodash_1.truncate)(str, { length: width, omission: truncater }) : str) + (0, lodash_1.repeat)(' ', style['padding-right'] || 0)); }; if (!head.length && !this.length) return ''; if (!colWidths.length) { let allRows = this.slice(0); if (head.length) { allRows = allRows.concat([head]); } allRows.forEach(function (cells) { // horizontal (arrays) if (typeof cells === 'object' && cells.length) { extractColumnWidths(cells); // vertical (objects) } else { const header_cell = Object.keys(cells)[0], value_cell = cells[header_cell]; colWidths[0] = Math.max(colWidths[0] || 0, getWidth(header_cell) || 0); // cross (objects w/ array values) if (typeof value_cell === 'object' && value_cell.length) { extractColumnWidths(value_cell, 1); } else { colWidths[1] = Math.max(colWidths[1] || 0, getWidth(value_cell) || 0); } } }); } totalWidth = (colWidths.length === 1 ? colWidths[0] : colWidths.reduce(function (a, b) { return a + b; })) + colWidths.length + 1; function extractColumnWidths(arr, offset = 0) { offset = offset || 0; arr.forEach(function (cell, i) { colWidths[i + offset] = Math.max(colWidths[i + offset] || 0, getWidth(cell) || 0); }); } // draws a line function line(line = '', left = '', right = '', intersection = '') { var _a; let width = 0; line = left + (0, lodash_1.repeat)(line, totalWidth - 2) + right; colWidths.forEach(function (w, i) { if (i === colWidths.length - 1) return; width += w + 1; line = line.substr(0, width) + intersection + line.substr(width + 1); }); return applyStyles((_a = options.style) === null || _a === void 0 ? void 0 : _a.border, line); } // draws the top line function lineTop() { const l = line(chars.top, chars['top-left'] || chars.top, chars['top-right'] || chars.top, chars['top-mid']); if (l) ret += l + '\n'; } function generateRow(items, style) { var _a; const cells = []; let max_height = 0; let first_cell_head = false; // prepare vertical and cross table data if (!Array.isArray(items) && typeof items === 'object') { const key = Object.keys(items)[0]; const value = items[key]; first_cell_head = true; if (Array.isArray(value)) { items = value; items.unshift(key); } else { items = [key, value]; } } // transform array of item strings into structure of cells items.forEach(function (item, i) { const contents = item .toString() .split('\n') .reduce(function (memo, l) { memo.push(renderString(l, i)); return memo; }, []); const height = contents.length; if (height > max_height) { max_height = height; } cells.push({ contents: contents, height: height }); }); // transform vertical cells into horizontal lines const lines = new Array(max_height); cells.forEach(function (cell, i) { cell.contents.forEach(function (line, j) { var _a, _b; if (!lines[j]) { lines[j] = []; } if (style || (first_cell_head && i === 0 && ((_a = options.style) === null || _a === void 0 ? void 0 : _a.head))) { line = applyStyles((_b = options.style) === null || _b === void 0 ? void 0 : _b.head, line); } lines[j].push(line); }); // populate empty lines in cell for (let j = cell.height, l = max_height; j < l; j++) { if (!lines[j]) { lines[j] = []; } lines[j].push(renderString('', i)); } }); let ret = ''; lines.forEach(function (line) { var _a, _b, _c; if (ret.length > 0) { ret += '\n' + applyStyles((_a = options.style) === null || _a === void 0 ? void 0 : _a.border, chars.left); } ret += line.join(applyStyles((_b = options.style) === null || _b === void 0 ? void 0 : _b.border, chars.middle)) + applyStyles((_c = options.style) === null || _c === void 0 ? void 0 : _c.border, chars.right); }); return applyStyles((_a = options.style) === null || _a === void 0 ? void 0 : _a.border, chars.left) + ret; } function applyStyles(styles = [], subject) { if (!subject) return ''; styles.forEach(function (style) { subject = chalk_1.default[style](subject); }); return subject; } if (head.length) { lineTop(); ret += generateRow(head, style.head) + '\n'; } if (this.length) this.forEach(function (cells, i) { if (!head.length && i === 0) lineTop(); else { if (!style.compact || i < Number(!!head.length) ? 1 : 0 || cells.length === 0) { const l = line(chars.mid, chars['left-mid'], chars['right-mid'], chars['mid-mid']); if (l) ret += l + '\n'; } } if (Object.prototype.hasOwnProperty.call(cells, 'length') && !cells.length) { return; } else { ret += generateRow(cells) + '\n'; } }); const l = line(chars.bottom, chars['bottom-left'] || chars.bottom, chars['bottom-right'] || chars.bottom, chars['bottom-mid']); if (l) ret += l; // trim the last '\n' if we didn't add the bottom decoration else ret = ret.slice(0, -1); return ret; } toString() { return this.render(); } } exports.ConsoleCliTable = ConsoleCliTable; //# sourceMappingURL=table.js.map