Initial commit
This commit is contained in:
17
node_modules/table-layout/lib/ansi.js
generated
vendored
Normal file
17
node_modules/table-layout/lib/ansi.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
'use strict'
|
||||
|
||||
const ansiEscapeSequence = /\u001b.*?m/g
|
||||
|
||||
/**
|
||||
* @module ansi
|
||||
*/
|
||||
exports.remove = remove
|
||||
exports.has = has
|
||||
|
||||
function remove (input) {
|
||||
return input.replace(ansiEscapeSequence, '')
|
||||
}
|
||||
|
||||
function has (input) {
|
||||
return ansiEscapeSequence.test(input)
|
||||
}
|
||||
29
node_modules/table-layout/lib/cell.js
generated
vendored
Normal file
29
node_modules/table-layout/lib/cell.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
'use strict'
|
||||
const t = require('typical')
|
||||
|
||||
const _value = new WeakMap()
|
||||
const _column = new WeakMap()
|
||||
|
||||
class Cell {
|
||||
constructor (value, column) {
|
||||
this.value = value
|
||||
_column.set(this, column)
|
||||
}
|
||||
|
||||
set value (val) {
|
||||
_value.set(this, val)
|
||||
}
|
||||
|
||||
get value () {
|
||||
let cellValue = _value.get(this)
|
||||
if (t.isFunction(cellValue)) cellValue = cellValue.call(_column.get(this))
|
||||
if (cellValue === undefined) {
|
||||
cellValue = ''
|
||||
} else {
|
||||
cellValue = String(cellValue)
|
||||
}
|
||||
return cellValue
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Cell
|
||||
68
node_modules/table-layout/lib/column.js
generated
vendored
Normal file
68
node_modules/table-layout/lib/column.js
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
'use strict'
|
||||
const t = require('typical')
|
||||
const Padding = require('./padding')
|
||||
|
||||
/**
|
||||
* @module column
|
||||
*/
|
||||
|
||||
const _padding = new WeakMap()
|
||||
|
||||
// setting any column property which is a factor of the width should trigger autoSize()
|
||||
|
||||
/**
|
||||
* Represents a table column
|
||||
*/
|
||||
class Column {
|
||||
constructor (column) {
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
if (t.isDefined(column.name)) this.name = column.name
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
if (t.isDefined(column.width)) this.width = column.width
|
||||
if (t.isDefined(column.maxWidth)) this.maxWidth = column.maxWidth
|
||||
if (t.isDefined(column.minWidth)) this.minWidth = column.minWidth
|
||||
if (t.isDefined(column.noWrap)) this.noWrap = column.noWrap
|
||||
if (t.isDefined(column.break)) this.break = column.break
|
||||
if (t.isDefined(column.contentWrappable)) this.contentWrappable = column.contentWrappable
|
||||
if (t.isDefined(column.contentWidth)) this.contentWidth = column.contentWidth
|
||||
if (t.isDefined(column.minContentWidth)) this.minContentWidth = column.minContentWidth
|
||||
this.padding = column.padding || { left: ' ', right: ' ' }
|
||||
this.generatedWidth = null
|
||||
}
|
||||
|
||||
set padding (padding) {
|
||||
_padding.set(this, new Padding(padding))
|
||||
}
|
||||
get padding () {
|
||||
return _padding.get(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* the width of the content (excluding padding) after being wrapped
|
||||
*/
|
||||
get wrappedContentWidth () {
|
||||
return Math.max(this.generatedWidth - this.padding.length(), 0)
|
||||
}
|
||||
|
||||
isResizable () {
|
||||
return !this.isFixed()
|
||||
}
|
||||
|
||||
isFixed () {
|
||||
return t.isDefined(this.width) || this.noWrap || !this.contentWrappable
|
||||
}
|
||||
|
||||
generateWidth () {
|
||||
this.generatedWidth = this.width || (this.contentWidth + this.padding.length())
|
||||
}
|
||||
|
||||
generateMinWidth () {
|
||||
this.minWidth = this.minContentWidth + this.padding.length()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Column
|
||||
157
node_modules/table-layout/lib/columns.js
generated
vendored
Normal file
157
node_modules/table-layout/lib/columns.js
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
'use strict'
|
||||
const t = require('typical')
|
||||
const arrayify = require('array-back')
|
||||
const Column = require('./column')
|
||||
const wrap = require('wordwrapjs')
|
||||
const Cell = require('./cell')
|
||||
const ansi = require('./ansi')
|
||||
|
||||
const _maxWidth = new WeakMap()
|
||||
|
||||
/**
|
||||
* @module columns
|
||||
*/
|
||||
|
||||
class Columns {
|
||||
constructor (columns) {
|
||||
this.list = []
|
||||
arrayify(columns).forEach(this.add.bind(this))
|
||||
}
|
||||
|
||||
/**
|
||||
* sum of all generatedWidth fields
|
||||
* @return {number}
|
||||
*/
|
||||
totalWidth () {
|
||||
return this.list.length
|
||||
? this.list.map(col => col.generatedWidth).reduce((a, b) => a + b)
|
||||
: 0
|
||||
}
|
||||
|
||||
totalFixedWidth () {
|
||||
return this.getFixed()
|
||||
.map(col => col.generatedWidth)
|
||||
.reduce((a, b) => a + b, 0)
|
||||
}
|
||||
|
||||
get (columnName) {
|
||||
return this.list.find(column => column.name === columnName)
|
||||
}
|
||||
|
||||
getResizable () {
|
||||
return this.list.filter(column => column.isResizable())
|
||||
}
|
||||
|
||||
getFixed () {
|
||||
return this.list.filter(column => column.isFixed())
|
||||
}
|
||||
|
||||
add (column) {
|
||||
const col = column instanceof Column ? column : new Column(column)
|
||||
this.list.push(col)
|
||||
return col
|
||||
}
|
||||
|
||||
set maxWidth (val) {
|
||||
_maxWidth.set(this, val)
|
||||
}
|
||||
|
||||
/**
|
||||
* sets `generatedWidth` for each column
|
||||
* @chainable
|
||||
*/
|
||||
autoSize () {
|
||||
const maxWidth = _maxWidth.get(this)
|
||||
|
||||
/* size */
|
||||
this.list.forEach(column => {
|
||||
column.generateWidth()
|
||||
column.generateMinWidth()
|
||||
})
|
||||
|
||||
/* adjust if user set a min or maxWidth */
|
||||
this.list.forEach(column => {
|
||||
if (t.isDefined(column.maxWidth) && column.generatedWidth > column.maxWidth) {
|
||||
column.generatedWidth = column.maxWidth
|
||||
}
|
||||
|
||||
if (t.isDefined(column.minWidth) && column.generatedWidth < column.minWidth) {
|
||||
column.generatedWidth = column.minWidth
|
||||
}
|
||||
})
|
||||
|
||||
const width = {
|
||||
total: this.totalWidth(),
|
||||
view: maxWidth,
|
||||
diff: this.totalWidth() - maxWidth,
|
||||
totalFixed: this.totalFixedWidth(),
|
||||
totalResizable: Math.max(maxWidth - this.totalFixedWidth(), 0)
|
||||
}
|
||||
|
||||
/* adjust if short of space */
|
||||
if (width.diff > 0) {
|
||||
/* share the available space between resizeable columns */
|
||||
let resizableColumns = this.getResizable()
|
||||
resizableColumns.forEach(column => {
|
||||
column.generatedWidth = Math.floor(width.totalResizable / resizableColumns.length)
|
||||
})
|
||||
|
||||
/* at this point, the generatedWidth should never end up bigger than the contentWidth */
|
||||
const grownColumns = this.list.filter(column => column.generatedWidth > column.contentWidth)
|
||||
const shrunkenColumns = this.list.filter(column => column.generatedWidth < column.contentWidth)
|
||||
let salvagedSpace = 0
|
||||
grownColumns.forEach(column => {
|
||||
const currentGeneratedWidth = column.generatedWidth
|
||||
column.generateWidth()
|
||||
salvagedSpace += currentGeneratedWidth - column.generatedWidth
|
||||
})
|
||||
shrunkenColumns.forEach(column => {
|
||||
column.generatedWidth += Math.floor(salvagedSpace / shrunkenColumns.length)
|
||||
})
|
||||
|
||||
/* if, after autosizing, we still don't fit within maxWidth then give up */
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method returning all distinct columns from input
|
||||
* @param {object[]} - input recordset
|
||||
* @return {module:columns}
|
||||
*/
|
||||
static getColumns (rows) {
|
||||
var columns = new Columns()
|
||||
arrayify(rows).forEach(row => {
|
||||
for (let columnName in row) {
|
||||
let column = columns.get(columnName)
|
||||
if (!column) {
|
||||
column = columns.add({ name: columnName, contentWidth: 0, minContentWidth: 0 })
|
||||
}
|
||||
let cell = new Cell(row[columnName], column)
|
||||
let cellValue = cell.value
|
||||
if (ansi.has(cellValue)) {
|
||||
cellValue = ansi.remove(cellValue)
|
||||
}
|
||||
|
||||
if (cellValue.length > column.contentWidth) column.contentWidth = cellValue.length
|
||||
|
||||
let longestWord = getLongestWord(cellValue)
|
||||
if (longestWord > column.minContentWidth) {
|
||||
column.minContentWidth = longestWord
|
||||
}
|
||||
if (!column.contentWrappable) column.contentWrappable = wrap.isWrappable(cellValue)
|
||||
}
|
||||
})
|
||||
return columns
|
||||
}
|
||||
}
|
||||
|
||||
function getLongestWord (line) {
|
||||
const words = wrap.getChunks(line)
|
||||
return words.reduce((max, word) => {
|
||||
return Math.max(word.length, max)
|
||||
}, 0)
|
||||
}
|
||||
|
||||
module.exports = Columns
|
||||
16
node_modules/table-layout/lib/padding.js
generated
vendored
Normal file
16
node_modules/table-layout/lib/padding.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
'use strict'
|
||||
|
||||
class Padding {
|
||||
constructor (padding) {
|
||||
this.left = padding.left
|
||||
this.right = padding.right
|
||||
}
|
||||
length () {
|
||||
return this.left.length + this.right.length
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@module padding
|
||||
*/
|
||||
module.exports = Padding
|
||||
53
node_modules/table-layout/lib/rows.js
generated
vendored
Normal file
53
node_modules/table-layout/lib/rows.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
'use strict'
|
||||
const arrayify = require('array-back')
|
||||
const Cell = require('./cell')
|
||||
const t = require('typical')
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Rows {
|
||||
constructor (rows, columns) {
|
||||
this.list = []
|
||||
this.load(rows, columns)
|
||||
}
|
||||
|
||||
load (rows, columns) {
|
||||
arrayify(rows).forEach(row => {
|
||||
this.list.push(new Map(objectToIterable(row, columns)))
|
||||
})
|
||||
}
|
||||
|
||||
static removeEmptyColumns (data) {
|
||||
const distinctColumnNames = data.reduce((columnNames, row) => {
|
||||
Object.keys(row).forEach(key => {
|
||||
if (columnNames.indexOf(key) === -1) columnNames.push(key)
|
||||
})
|
||||
return columnNames
|
||||
}, [])
|
||||
|
||||
const emptyColumns = distinctColumnNames.filter(columnName => {
|
||||
const hasValue = data.some(row => {
|
||||
const value = row[columnName]
|
||||
return (t.isDefined(value) && !t.isString(value)) || (t.isString(value) && /\S+/.test(value))
|
||||
})
|
||||
return !hasValue
|
||||
})
|
||||
|
||||
return data.map(row => {
|
||||
emptyColumns.forEach(emptyCol => delete row[emptyCol])
|
||||
return row
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function objectToIterable (row, columns) {
|
||||
return columns.list.map(column => {
|
||||
return [ column, new Cell(row[column.name], column) ]
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @module rows
|
||||
*/
|
||||
module.exports = Rows
|
||||
Reference in New Issue
Block a user