1const debug = require('./debug'); 2const utils = require('./utils'); 3const tableLayout = require('./layout-manager'); 4 5class Table extends Array { 6 constructor(opts) { 7 super(); 8 9 const options = utils.mergeOptions(opts); 10 Object.defineProperty(this, 'options', { 11 value: options, 12 enumerable: options.debug, 13 }); 14 15 if (options.debug) { 16 switch (typeof options.debug) { 17 case 'boolean': 18 debug.setDebugLevel(debug.WARN); 19 break; 20 case 'number': 21 debug.setDebugLevel(options.debug); 22 break; 23 case 'string': 24 debug.setDebugLevel(parseInt(options.debug, 10)); 25 break; 26 default: 27 debug.setDebugLevel(debug.WARN); 28 debug.warn(`Debug option is expected to be boolean, number, or string. Received a ${typeof options.debug}`); 29 } 30 Object.defineProperty(this, 'messages', { 31 get() { 32 return debug.debugMessages(); 33 }, 34 }); 35 } 36 } 37 38 toString() { 39 let array = this; 40 let headersPresent = this.options.head && this.options.head.length; 41 if (headersPresent) { 42 array = [this.options.head]; 43 if (this.length) { 44 array.push.apply(array, this); 45 } 46 } else { 47 this.options.style.head = []; 48 } 49 50 let cells = tableLayout.makeTableLayout(array); 51 52 cells.forEach(function (row) { 53 row.forEach(function (cell) { 54 cell.mergeTableOptions(this.options, cells); 55 }, this); 56 }, this); 57 58 tableLayout.computeWidths(this.options.colWidths, cells); 59 tableLayout.computeHeights(this.options.rowHeights, cells); 60 61 cells.forEach(function (row) { 62 row.forEach(function (cell) { 63 cell.init(this.options); 64 }, this); 65 }, this); 66 67 let result = []; 68 69 for (let rowIndex = 0; rowIndex < cells.length; rowIndex++) { 70 let row = cells[rowIndex]; 71 let heightOfRow = this.options.rowHeights[rowIndex]; 72 73 if (rowIndex === 0 || !this.options.style.compact || (rowIndex == 1 && headersPresent)) { 74 doDraw(row, 'top', result); 75 } 76 77 for (let lineNum = 0; lineNum < heightOfRow; lineNum++) { 78 doDraw(row, lineNum, result); 79 } 80 81 if (rowIndex + 1 == cells.length) { 82 doDraw(row, 'bottom', result); 83 } 84 } 85 86 return result.join('\n'); 87 } 88 89 get width() { 90 let str = this.toString().split('\n'); 91 return str[0].length; 92 } 93} 94 95Table.reset = () => debug.reset(); 96 97function doDraw(row, lineNum, result) { 98 let line = []; 99 row.forEach(function (cell) { 100 line.push(cell.draw(lineNum)); 101 }); 102 let str = line.join(''); 103 if (str.length) result.push(str); 104} 105 106module.exports = Table; 107