aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2022-01-26 13:57:40 -0500
committerBobby <[email protected]>2022-01-26 13:57:40 -0500
commit901901f0cc4795305d368f588a2d18fe2a8e28b2 (patch)
treedbaf30463ef987e9d6727b3afe783e3d53021b50
parent235a6523cc3239193bb908ae91da7426929d79ab (diff)
downloadizuku.js-901901f0cc4795305d368f588a2d18fe2a8e28b2.tar.xz
izuku.js-901901f0cc4795305d368f588a2d18fe2a8e28b2.zip
feat: inbuilt table functionality
-rw-r--r--package-lock.json582
-rw-r--r--package.json1
-rw-r--r--src/helpers/tableBuilder/index.ts9
-rw-r--r--src/helpers/tableBuilder/src/console-table-printer.ts47
-rw-r--r--src/helpers/tableBuilder/src/internalTable/input-converter.ts25
-rw-r--r--src/helpers/tableBuilder/src/internalTable/internal-table-printer.ts220
-rw-r--r--src/helpers/tableBuilder/src/internalTable/internal-table.ts141
-rw-r--r--src/helpers/tableBuilder/src/internalTable/table-pre-processors.ts53
-rw-r--r--src/helpers/tableBuilder/src/models/common.ts13
-rw-r--r--src/helpers/tableBuilder/src/models/external-table.ts34
-rw-r--r--src/helpers/tableBuilder/src/models/internal-table.ts31
-rw-r--r--src/helpers/tableBuilder/src/utils/colored-console-line.ts35
-rw-r--r--src/helpers/tableBuilder/src/utils/console-utils.ts9
-rw-r--r--src/helpers/tableBuilder/src/utils/string-utils.ts57
-rw-r--r--src/helpers/tableBuilder/src/utils/table-constants.ts62
-rw-r--r--src/helpers/tableBuilder/src/utils/table-helpers.ts154
-rw-r--r--src/lib/display.ts37
-rw-r--r--tests/simple.test.ts10
18 files changed, 1434 insertions, 86 deletions
diff --git a/package-lock.json b/package-lock.json
index a81df1d..b600c03 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,7 @@
"license": "MIT",
"dependencies": {
"buffer": "^6.0.3",
+ "simple-wcswidth": "^1.0.1",
"table": "^6.8.0"
},
"devDependencies": {
@@ -118,6 +119,18 @@
"node": ">=0.8.0"
}
},
+ "node_modules/@babel/highlight/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/@commitlint/cli": {
"version": "16.0.2",
"resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-16.0.2.tgz",
@@ -210,6 +223,43 @@
"node": ">=v12"
}
},
+ "node_modules/@commitlint/format/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@commitlint/format/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@commitlint/format/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@commitlint/is-ignored": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-16.0.0.tgz",
@@ -274,6 +324,31 @@
"node": ">=v12"
}
},
+ "node_modules/@commitlint/load/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@commitlint/load/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@commitlint/load/node_modules/resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@@ -283,6 +358,18 @@
"node": ">=8"
}
},
+ "node_modules/@commitlint/load/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@commitlint/message": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.0.0.tgz",
@@ -396,6 +483,43 @@
"node": ">=v12"
}
},
+ "node_modules/@commitlint/types/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@commitlint/types/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@commitlint/types/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@cspotcode/source-map-consumer": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
@@ -1172,6 +1296,43 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/boxen/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/boxen/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/boxen/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -1329,43 +1490,6 @@
"node": ">=4"
}
},
- "node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/chalk/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/chalk/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/check-error": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
@@ -1932,6 +2056,22 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
+ "node_modules/eslint/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
"node_modules/eslint/node_modules/debug": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
@@ -1983,6 +2123,15 @@
"node": ">=10.13.0"
}
},
+ "node_modules/eslint/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/eslint/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -2001,6 +2150,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/eslint/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/espree": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz",
@@ -2997,6 +3158,43 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/log-symbols/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/log-symbols/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/log-symbols/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/lowercase-keys": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
@@ -3416,6 +3614,18 @@
"url": "https://opencollective.com/nodemon"
}
},
+ "node_modules/nodemon/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/nopt": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
@@ -4255,6 +4465,11 @@
"integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==",
"dev": true
},
+ "node_modules/simple-wcswidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-wcswidth/-/simple-wcswidth-1.0.1.tgz",
+ "integrity": "sha512-xMO/8eNREtaROt7tJvWJqHBDTMFN4eiQ5I4JRMuilwfnFcV5W9u7RUkueNkdw0jPqGMX36iCywelS5yilTuOxg=="
+ },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -4384,18 +4599,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
@@ -4687,6 +4890,31 @@
"url": "https://github.com/yeoman/update-notifier?sponsor=1"
}
},
+ "node_modules/update-notifier/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/update-notifier/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/update-notifier/node_modules/semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
@@ -4702,6 +4930,18 @@
"node": ">=10"
}
},
+ "node_modules/update-notifier/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -5015,6 +5255,15 @@
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
}
}
},
@@ -5086,6 +5335,33 @@
"requires": {
"@commitlint/types": "^16.0.0",
"chalk": "^4.0.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
}
},
"@commitlint/is-ignored": {
@@ -5139,11 +5415,36 @@
"typescript": "^4.4.3"
},
"dependencies": {
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
"resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
}
}
},
@@ -5233,6 +5534,33 @@
"dev": true,
"requires": {
"chalk": "^4.0.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
}
},
"@cspotcode/source-map-consumer": {
@@ -5771,6 +6099,33 @@
"type-fest": "^0.20.2",
"widest-line": "^3.1.0",
"wrap-ansi": "^7.0.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
}
},
"brace-expansion": {
@@ -5884,33 +6239,6 @@
"type-detect": "^4.0.5"
}
},
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "dependencies": {
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
"check-error": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
@@ -6287,6 +6615,16 @@
"v8-compile-cache": "^2.0.3"
},
"dependencies": {
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"debug": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
@@ -6321,6 +6659,12 @@
"is-glob": "^4.0.3"
}
},
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -6332,6 +6676,15 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
}
}
},
@@ -7115,6 +7468,33 @@
"requires": {
"chalk": "^4.1.0",
"is-unicode-supported": "^0.1.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
}
},
"lowercase-keys": {
@@ -7417,6 +7797,17 @@
"touch": "^3.1.0",
"undefsafe": "^2.0.5",
"update-notifier": "^5.1.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
}
},
"nopt": {
@@ -8015,6 +8406,11 @@
"integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==",
"dev": true
},
+ "simple-wcswidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-wcswidth/-/simple-wcswidth-1.0.1.tgz",
+ "integrity": "sha512-xMO/8eNREtaROt7tJvWJqHBDTMFN4eiQ5I4JRMuilwfnFcV5W9u7RUkueNkdw0jPqGMX36iCywelS5yilTuOxg=="
+ },
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -8120,15 +8516,6 @@
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"dev": true
},
- "supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "requires": {
- "has-flag": "^3.0.0"
- }
- },
"supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
@@ -8336,6 +8723,22 @@
"xdg-basedir": "^4.0.0"
},
"dependencies": {
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
@@ -8344,6 +8747,15 @@
"requires": {
"lru-cache": "^6.0.0"
}
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
}
}
},
diff --git a/package.json b/package.json
index 6411e93..499b166 100644
--- a/package.json
+++ b/package.json
@@ -61,6 +61,7 @@
},
"dependencies": {
"buffer": "^6.0.3",
+ "simple-wcswidth": "^1.0.1",
"table": "^6.8.0"
}
}
diff --git a/src/helpers/tableBuilder/index.ts b/src/helpers/tableBuilder/index.ts
new file mode 100644
index 0000000..bf29228
--- /dev/null
+++ b/src/helpers/tableBuilder/index.ts
@@ -0,0 +1,9 @@
+import Table from './src/console-table-printer';
+import {
+ printSimpleTable as printTable,
+ renderSimpleTable as renderTable
+} from './src/internalTable/internal-table-printer';
+
+import { COLOR, ALIGNMENT } from './src/models/external-table';
+
+export { Table, printTable, renderTable, COLOR, ALIGNMENT };
diff --git a/src/helpers/tableBuilder/src/console-table-printer.ts b/src/helpers/tableBuilder/src/console-table-printer.ts
new file mode 100644
index 0000000..cc43b74
--- /dev/null
+++ b/src/helpers/tableBuilder/src/console-table-printer.ts
@@ -0,0 +1,47 @@
+import TableInternal from './internalTable/internal-table';
+import { Dictionary } from './models/common';
+import { ComplexOptions } from './models/external-table';
+import {
+ convertRawRowOptionsToStandard,
+ RowOptionsRaw
+} from './utils/table-helpers';
+
+export default class Table {
+ table: TableInternal;
+
+ constructor(options?: ComplexOptions | string[]) {
+ this.table = new TableInternal(options);
+ }
+
+ addColumn(column: string) {
+ this.table.addColumn(column);
+ return this;
+ }
+
+ addColumns(columns: string[]) {
+ this.table.addColumns(columns);
+ return this;
+ }
+
+ addRow(text: Dictionary, rowOptions?: RowOptionsRaw) {
+ this.table.addRow(text, convertRawRowOptionsToStandard(rowOptions));
+ return this;
+ }
+
+ addRows(toBeInsertedRows: any, rowOptions?: RowOptionsRaw) {
+ this.table.addRows(
+ toBeInsertedRows,
+ convertRawRowOptionsToStandard(rowOptions)
+ );
+ return this;
+ }
+
+ printTable() {
+ const tableRendered = this.table.renderTable();
+ console.log(tableRendered);
+ }
+
+ render() {
+ return this.table.renderTable();
+ }
+}
diff --git a/src/helpers/tableBuilder/src/internalTable/input-converter.ts b/src/helpers/tableBuilder/src/internalTable/input-converter.ts
new file mode 100644
index 0000000..c3800e6
--- /dev/null
+++ b/src/helpers/tableBuilder/src/internalTable/input-converter.ts
@@ -0,0 +1,25 @@
+import { COLOR } from '../models/common';
+import { ColumnOptionsRaw } from '../models/external-table';
+import { Column } from '../models/internal-table';
+import { DEFAULT_ROW_ALIGNMENT } from '../utils/table-constants';
+
+export const objIfExists = (key: string, val: any) => {
+ if (!val) {
+ return {};
+ }
+
+ return {
+ [key]: val,
+ };
+};
+
+export const rawColumnToInternalColumn = (
+ column: ColumnOptionsRaw
+): Column => ({
+ name: column.name,
+ title: column.title || column.name,
+ ...objIfExists('color', column.color as COLOR),
+ ...objIfExists('maxLen', column.maxLen),
+ ...objIfExists('minLen', column.minLen),
+ alignment: column.alignment || DEFAULT_ROW_ALIGNMENT,
+});
diff --git a/src/helpers/tableBuilder/src/internalTable/internal-table-printer.ts b/src/helpers/tableBuilder/src/internalTable/internal-table-printer.ts
new file mode 100644
index 0000000..ffdeb59
--- /dev/null
+++ b/src/helpers/tableBuilder/src/internalTable/internal-table-printer.ts
@@ -0,0 +1,220 @@
+import { Row } from '../models/common';
+import { Column, TableStyleDetails } from '../models/internal-table';
+import ColoredConsoleLine from '../utils/colored-console-line';
+import { textWithPadding } from '../utils/string-utils';
+import {
+ DEFAULT_COLUMN_LEN,
+ DEFAULT_HEADER_ALIGNMENT,
+ DEFAULT_HEADER_FONT_COLOR,
+ DEFAULT_ROW_ALIGNMENT,
+ DEFAULT_ROW_FONT_COLOR,
+} from '../utils/table-constants';
+import {
+ cellText,
+ createHeaderAsRow,
+ createRow,
+ getWidthLimitedColumnsArray,
+ renderTableHorizontalBorders,
+} from '../utils/table-helpers';
+import TableInternal from './internal-table';
+import { preProcessColumns, preProcessRows } from './table-pre-processors';
+
+// ║ Index ║ ║ ║
+const renderOneLine = (
+ tableStyle: TableStyleDetails,
+ columns: Column[],
+ currentLineIndex: number,
+ widthLimitedColumnsArray: { [key: string]: string[] },
+ isHeader: boolean | undefined,
+ row: Row
+): string => {
+ const line = new ColoredConsoleLine();
+ line.addCharsWithColor(DEFAULT_ROW_FONT_COLOR, tableStyle.vertical);
+ columns.forEach((column) => {
+ const thisLineHasText =
+ currentLineIndex < widthLimitedColumnsArray[column.name].length;
+
+ const textForThisLine: string = thisLineHasText
+ ? cellText(widthLimitedColumnsArray[column.name][currentLineIndex])
+ : '';
+
+ line.addCharsWithColor(DEFAULT_ROW_FONT_COLOR, ' ');
+ line.addCharsWithColor(
+ (isHeader && DEFAULT_HEADER_FONT_COLOR) || column.color || row.color,
+ textWithPadding(
+ textForThisLine,
+ column.alignment || DEFAULT_ROW_ALIGNMENT,
+ column.length || DEFAULT_COLUMN_LEN
+ )
+ );
+ line.addCharsWithColor(DEFAULT_ROW_FONT_COLOR, ` ${tableStyle.vertical}`);
+ });
+ return line.renderConsole();
+};
+
+// ║ Bold ║ text ║ value ║
+// ║ Index ║ ║ ║
+const renderWidthLimitedLines = (
+ tableStyle: TableStyleDetails,
+ columns: Column[],
+ row: Row,
+ isHeader?: boolean
+): string[] => {
+ // { col1: ['How', 'Is', 'Going'], col2: ['I am', 'Tom'], }
+ const widthLimitedColumnsArray = getWidthLimitedColumnsArray(columns, row);
+
+ const totalLines = Object.values(widthLimitedColumnsArray).reduce(
+ (a, b) => Math.max(a, b.length),
+ 0
+ );
+
+ const ret = [];
+ for (
+ let currentLineIndex = 0;
+ currentLineIndex < totalLines;
+ currentLineIndex += 1
+ ) {
+ const singleLine = renderOneLine(
+ tableStyle,
+ columns,
+ currentLineIndex,
+ widthLimitedColumnsArray,
+ isHeader,
+ row
+ );
+
+ ret.push(singleLine);
+ }
+
+ return ret;
+};
+
+// ║ 1 ║ I would like some red wine please ║ 10.212 ║
+const renderRow = (table: TableInternal, row: Row): string[] => {
+ let ret: string[] = [];
+ ret = ret.concat(
+ renderWidthLimitedLines(table.tableStyle, table.columns, row)
+ );
+ return ret;
+};
+
+/*
+ The analysis Result
+ ╔═══════╦═══════════════════════════════════════╦════════╗
+*/
+const renderTableTitle = (table: TableInternal): string[] => {
+ const ret: string[] = [];
+
+ if (table.title === undefined) {
+ return ret;
+ }
+
+ const getTableWidth = () => {
+ const reducer = (accumulator: number, currentValue: number) =>
+ // ║ cell ║, 2 spaces + cellTextSize + one border on the left
+ accumulator + currentValue + 2 + 1;
+ return table.columns
+ .map((m) => m.length || DEFAULT_COLUMN_LEN)
+ .reduce(reducer, 1);
+ };
+
+ const titleWithPadding = textWithPadding(
+ table.title as string,
+ DEFAULT_HEADER_ALIGNMENT,
+ getTableWidth()
+ );
+ const styledText = new ColoredConsoleLine();
+ styledText.addCharsWithColor(DEFAULT_HEADER_FONT_COLOR, titleWithPadding);
+ // The analysis Result
+ ret.push(styledText.renderConsole());
+ return ret;
+};
+
+/*
+ ╔═══════╦═══════════════════════════════════════╦════════╗
+ ║ index ║ text ║ value ║
+ ╟═══════╬═══════════════════════════════════════╬════════╢
+*/
+const renderTableHeaders = (table: TableInternal): string[] => {
+ let ret: string[] = [];
+
+ // ╔═══════╦═══════════════════════════════════════╦════════╗
+ ret.push(
+ renderTableHorizontalBorders(
+ table.tableStyle.headerTop,
+ table.columns.map((m: Column) => m.length || DEFAULT_COLUMN_LEN)
+ )
+ );
+
+ // ║ index ║ text ║ value ║
+ const row = createHeaderAsRow(createRow, table.columns);
+ ret = ret.concat(
+ renderWidthLimitedLines(table.tableStyle, table.columns, row, true)
+ );
+
+ // ╟═══════╬═══════════════════════════════════════╬════════╢
+ ret.push(
+ renderTableHorizontalBorders(
+ table.tableStyle.headerBottom,
+ table.columns.map((m) => m.length || DEFAULT_COLUMN_LEN)
+ )
+ );
+
+ return ret;
+};
+
+const renderTableEnding = (table: TableInternal): string[] => {
+ const ret: string[] = [];
+ // ╚═══════╩═══════════════════════════════════════╩════════╝
+ ret.push(
+ renderTableHorizontalBorders(
+ table.tableStyle.tableBottom,
+ table.columns.map((m) => m.length || DEFAULT_COLUMN_LEN)
+ )
+ );
+ return ret;
+};
+
+const renderRowSeparator = (table: TableInternal, row: Row): string[] => {
+ const ret: string[] = [];
+ const lastRowIndex = table.rows.length - 1;
+ const currentRowIndex = table.rows.indexOf(row);
+
+ if (currentRowIndex !== lastRowIndex && row.separator) {
+ // ╟═══════╬═══════════════════════════════════════╬════════╢
+ ret.push(
+ renderTableHorizontalBorders(
+ table.tableStyle.rowSeparator,
+ table.columns.map((m) => m.length || DEFAULT_COLUMN_LEN)
+ )
+ );
+ }
+ return ret;
+};
+
+export const renderTable = (table: TableInternal): string => {
+ preProcessColumns(table); // enable / disable cols, find maxLn of each col/ computed Columns
+ preProcessRows(table); // sort and filter
+
+ const ret: string[] = [];
+ renderTableTitle(table).forEach((row) => ret.push(row));
+
+ renderTableHeaders(table).forEach((row) => ret.push(row));
+
+ table.rows.forEach((row) => {
+ renderRow(table, row).forEach((row_) => ret.push(row_));
+ renderRowSeparator(table, row).forEach((row_) => ret.push(row_));
+ });
+ renderTableEnding(table).forEach((row) => ret.push(row));
+ return ret.join('\n');
+};
+
+export const renderSimpleTable = (rows: any[]) => {
+ const table = new TableInternal();
+ table.addRows(rows);
+ return renderTable(table);
+};
+
+export const printSimpleTable = (rows: any[]) => {
+ console.log(renderSimpleTable(rows));
+};
diff --git a/src/helpers/tableBuilder/src/internalTable/internal-table.ts b/src/helpers/tableBuilder/src/internalTable/internal-table.ts
new file mode 100644
index 0000000..a7b443f
--- /dev/null
+++ b/src/helpers/tableBuilder/src/internalTable/internal-table.ts
@@ -0,0 +1,141 @@
+import { Dictionary, Row } from '../models/common';
+import {
+ ComplexOptions,
+ ComputedColumn,
+ RowFilterFunction,
+ RowSortFunction,
+} from '../models/external-table';
+import { Column, TableStyleDetails } from '../models/internal-table';
+import {
+ DEFAULT_TABLE_STYLE,
+ DEFAULT_ROW_ALIGNMENT,
+ DEFAULT_ROW_FONT_COLOR,
+ DEFAULT_ROW_SEPARATOR,
+} from '../utils/table-constants';
+import {
+ createColumFromComputedColumn,
+ createColumFromOnlyName,
+ createRow,
+ RowOptions,
+} from '../utils/table-helpers';
+import { rawColumnToInternalColumn } from './input-converter';
+import { renderTable } from './internal-table-printer';
+
+const DEFAULT_ROW_SORT_FUNC = () => 0;
+
+const DEFAULT_ROW_FILTER_FUNC = () => true;
+
+class TableInternal {
+ title?: string;
+
+ tableStyle: TableStyleDetails;
+
+ columns: Column[];
+
+ rows: Row[];
+
+ filterFunction: RowFilterFunction;
+
+ sortFunction: RowSortFunction;
+
+ enabledColumns: string[];
+
+ disabledColumns: string[];
+
+ computedColumns: any[];
+
+ rowSeparator: boolean;
+
+ initSimple(columns: string[]) {
+ this.columns = columns.map((column) => ({
+ name: column,
+ title: column,
+ alignment: DEFAULT_ROW_ALIGNMENT,
+ }));
+ }
+
+ initDetailed(options: ComplexOptions) {
+ this.title = options?.title || this.title;
+ this.tableStyle = options?.style || this.tableStyle;
+ this.sortFunction = options?.sort || this.sortFunction;
+ this.filterFunction = options?.filter || this.filterFunction;
+ this.enabledColumns = options?.enabledColumns || this.enabledColumns;
+ this.disabledColumns = options?.disabledColumns || this.disabledColumns;
+ this.computedColumns = options?.computedColumns || this.computedColumns;
+ this.columns =
+ options?.columns?.map(rawColumnToInternalColumn) || this.columns;
+ this.rowSeparator = options?.rowSeparator || this.rowSeparator;
+
+ if (options.rows !== undefined) {
+ this.addRows(options.rows);
+ }
+ }
+
+ constructor(options?: ComplexOptions | string[]) {
+ // default construction
+ this.rows = [];
+ this.columns = [];
+ this.title = undefined;
+ this.tableStyle = DEFAULT_TABLE_STYLE;
+ this.filterFunction = DEFAULT_ROW_FILTER_FUNC;
+ this.sortFunction = DEFAULT_ROW_SORT_FUNC;
+ this.enabledColumns = [];
+ this.disabledColumns = [];
+ this.computedColumns = [];
+ this.rowSeparator = DEFAULT_ROW_SEPARATOR;
+
+ if (options instanceof Array) {
+ this.initSimple(options);
+ } else if (typeof options === 'object') {
+ this.initDetailed(options);
+ }
+ }
+
+ createColumnFromRow(text: Dictionary) {
+ const colNames = this.columns.map((col) => col.name);
+ Object.keys(text).forEach((key) => {
+ if (!colNames.includes(key)) {
+ this.columns.push(createColumFromOnlyName(key));
+ }
+ });
+ }
+
+ addColumn(textOrObj: string | ComputedColumn) {
+ if (typeof textOrObj === 'string') {
+ this.columns.push(createColumFromOnlyName(textOrObj));
+ } else {
+ this.columns.push(createColumFromComputedColumn(textOrObj));
+ }
+ }
+
+ addColumns(toBeInsertedColumns: string[]) {
+ toBeInsertedColumns.forEach((toBeInsertedColumn) => {
+ this.addColumn(toBeInsertedColumn);
+ });
+ }
+
+ addRow(text: Dictionary, options?: RowOptions) {
+ this.createColumnFromRow(text);
+ this.rows.push(
+ createRow(
+ options?.color || DEFAULT_ROW_FONT_COLOR,
+ text,
+ options?.separator !== undefined
+ ? options?.separator
+ : this.rowSeparator
+ )
+ );
+ }
+
+ addRows(toBeInsertedRows: Dictionary[], options?: RowOptions) {
+ toBeInsertedRows.forEach((toBeInsertedRow) => {
+ this.addRow(toBeInsertedRow, options);
+ });
+ }
+
+ renderTable() {
+ return renderTable(this);
+ }
+}
+
+export default TableInternal;
diff --git a/src/helpers/tableBuilder/src/internalTable/table-pre-processors.ts b/src/helpers/tableBuilder/src/internalTable/table-pre-processors.ts
new file mode 100644
index 0000000..1b8ef87
--- /dev/null
+++ b/src/helpers/tableBuilder/src/internalTable/table-pre-processors.ts
@@ -0,0 +1,53 @@
+/* eslint-disable no-param-reassign */
+import { Row } from '../models/common';
+import { ComputedColumn } from '../models/external-table';
+import { Column } from '../models/internal-table';
+import { findLenOfColumn } from '../utils/table-helpers';
+import TableInternal from './internal-table';
+
+const createComputedColumnsIfNecessary = (table: TableInternal) => {
+ if (table.computedColumns.length) {
+ table.computedColumns.forEach((computedColumn: ComputedColumn) => {
+ table.addColumn(computedColumn);
+ table.rows.forEach((row: Row) => {
+ row.text[computedColumn.name] = computedColumn.function(row.text);
+ });
+ });
+ }
+};
+
+const disableColumnsIfNecessary = (table: TableInternal) => {
+ if (table.enabledColumns.length) {
+ table.columns = table.columns.filter((col: Column) =>
+ table.enabledColumns.includes(col.name)
+ );
+ }
+};
+
+const enableColumnsIfNecessary = (table: TableInternal) => {
+ if (table.disabledColumns.length) {
+ table.columns = table.columns.filter(
+ (col: Column) => !table.disabledColumns.includes(col.name)
+ );
+ }
+};
+
+const findColumnWidth = (table: TableInternal) => {
+ table.columns.forEach((column) => {
+ column.length = findLenOfColumn(column, table.rows);
+ });
+};
+
+export const preProcessColumns = (table: TableInternal) => {
+ createComputedColumnsIfNecessary(table);
+ enableColumnsIfNecessary(table);
+ disableColumnsIfNecessary(table);
+ findColumnWidth(table);
+};
+
+export const preProcessRows = (table: TableInternal) => {
+ const newRows = table.rows
+ .filter((r) => table.filterFunction(r.text))
+ .sort((r1, r2) => table.sortFunction(r1.text, r2.text));
+ table.rows = newRows;
+};
diff --git a/src/helpers/tableBuilder/src/models/common.ts b/src/helpers/tableBuilder/src/models/common.ts
new file mode 100644
index 0000000..6d2b9e6
--- /dev/null
+++ b/src/helpers/tableBuilder/src/models/common.ts
@@ -0,0 +1,13 @@
+import { ALIGNMENTS, COLORS } from '../utils/table-constants';
+
+export type ALIGNMENT = typeof ALIGNMENTS[number];
+
+export type COLOR = typeof COLORS[number];
+export interface Dictionary {
+ [key: string]: any;
+}
+export interface Row {
+ color: COLOR;
+ separator: boolean;
+ text: Dictionary;
+}
diff --git a/src/helpers/tableBuilder/src/models/external-table.ts b/src/helpers/tableBuilder/src/models/external-table.ts
new file mode 100644
index 0000000..4c2df30
--- /dev/null
+++ b/src/helpers/tableBuilder/src/models/external-table.ts
@@ -0,0 +1,34 @@
+import { ALIGNMENT, COLOR, Dictionary } from './common';
+import { TableStyleDetails } from './internal-table';
+
+export { ALIGNMENT, COLOR };
+
+export interface ColumnOptionsRaw {
+ name: string; // unique id
+ title?: string; // the value that will be printed, if not present this will be 'name'
+ alignment?: ALIGNMENT;
+ color?: COLOR;
+ maxLen?: number;
+ minLen?: number;
+}
+
+export interface ComputedColumn extends ColumnOptionsRaw {
+ function: (arg0: any) => any;
+}
+
+export type RowSortFunction = (row1: any, row2: any) => number;
+
+export type RowFilterFunction = (row: any) => Boolean;
+
+export interface ComplexOptions {
+ style?: TableStyleDetails;
+ title?: string;
+ columns?: ColumnOptionsRaw[];
+ rows?: Dictionary[];
+ sort?: RowSortFunction;
+ filter?: RowFilterFunction;
+ enabledColumns?: string[];
+ disabledColumns?: string[];
+ computedColumns?: ComputedColumn[];
+ rowSeparator?: boolean;
+}
diff --git a/src/helpers/tableBuilder/src/models/internal-table.ts b/src/helpers/tableBuilder/src/models/internal-table.ts
new file mode 100644
index 0000000..50d048a
--- /dev/null
+++ b/src/helpers/tableBuilder/src/models/internal-table.ts
@@ -0,0 +1,31 @@
+import { ALIGNMENT, COLOR } from './common';
+
+/*
+All the fields of Internal Table has to be mandatory
+These fields are generated based on user input
+and during generated is some input is missing it is filled by default value.
+*/
+
+export interface Column {
+ name: string;
+ title: string;
+ alignment?: ALIGNMENT;
+ color?: COLOR;
+ length?: number;
+ minLen?: number;
+ maxLen?: number;
+}
+
+type TableLineDetailsKeys = 'left' | 'right' | 'mid' | 'other';
+
+export type TableLineDetails = {
+ [key in TableLineDetailsKeys]: string;
+};
+
+export type TableStyleDetails = {
+ headerTop: TableLineDetails;
+ headerBottom: TableLineDetails;
+ tableBottom: TableLineDetails;
+ vertical: string;
+ rowSeparator?: TableLineDetails;
+};
diff --git a/src/helpers/tableBuilder/src/utils/colored-console-line.ts b/src/helpers/tableBuilder/src/utils/colored-console-line.ts
new file mode 100644
index 0000000..7de589d
--- /dev/null
+++ b/src/helpers/tableBuilder/src/utils/colored-console-line.ts
@@ -0,0 +1,35 @@
+import { COLOR } from '../models/common';
+
+const COLOR_MAP: {
+ [key in COLOR]?: string;
+} = {
+ red: '\x1b[31m',
+ green: '\x1b[32m',
+ yellow: '\x1b[33m',
+ blue: '\x1b[34m',
+ magenta: '\x1b[35m',
+ cyan: '\x1b[36m',
+ white: '\x1b[37m',
+ crimson: '\x1b[38m',
+ white_bold: '\x1b[01m',
+ reset: '\x1b[0m'
+};
+
+export const colorString = (color: COLOR, text: string) =>
+ `${color && COLOR_MAP[color]}${text}${COLOR_MAP.reset}`;
+
+export default class ColoredConsoleLine {
+ text: string;
+
+ constructor() {
+ this.text = '';
+ }
+
+ addCharsWithColor(color: COLOR, text: string) {
+ this.text += colorString(color, text);
+ }
+
+ renderConsole(): string {
+ return this.text;
+ }
+}
diff --git a/src/helpers/tableBuilder/src/utils/console-utils.ts b/src/helpers/tableBuilder/src/utils/console-utils.ts
new file mode 100644
index 0000000..93620c8
--- /dev/null
+++ b/src/helpers/tableBuilder/src/utils/console-utils.ts
@@ -0,0 +1,9 @@
+import { wcswidth } from 'simple-wcswidth';
+
+/* eslint-disable no-control-regex */
+const colorRegex = /\x1b\[\d{1,3}m/g; // \x1b[30m \x1b[305m
+
+const stripAnsi = (str: string): string => str.replace(colorRegex, '');
+const findWidthInConsole = (str: string): number => wcswidth(stripAnsi(str));
+
+export default findWidthInConsole;
diff --git a/src/helpers/tableBuilder/src/utils/string-utils.ts b/src/helpers/tableBuilder/src/utils/string-utils.ts
new file mode 100644
index 0000000..5155c73
--- /dev/null
+++ b/src/helpers/tableBuilder/src/utils/string-utils.ts
@@ -0,0 +1,57 @@
+import { ALIGNMENT } from '../models/common';
+import findWidthInConsole from './console-utils';
+
+// ("How are you?",center, 20) => " How are you? "
+// ("How are you?",right, 20) => " How are you?"
+export const textWithPadding = (
+ text: string,
+ alignment: ALIGNMENT,
+ columnLen: number
+): string => {
+ const curTextSize = findWidthInConsole(text);
+ // alignments for center padding case
+ const leftPadding = Math.floor((columnLen - curTextSize) / 2);
+ const rightPadding = columnLen - leftPadding - curTextSize;
+
+ // console.log(text, columnLen, curTextSize);
+ switch (alignment) {
+ case 'left':
+ return text.concat(' '.repeat(columnLen - curTextSize));
+ case 'center':
+ return ' '
+ .repeat(leftPadding)
+ .concat(text)
+ .concat(' '.repeat(rightPadding));
+ case 'right':
+ default:
+ return ' '.repeat(columnLen - curTextSize).concat(text);
+ }
+};
+
+// ("How are you?",10) => ["How are ", "you?"]
+export const limitWidth = (inpStr: string, width: number): string[] => {
+ const ret: string[] = [];
+
+ const spaceSeparatedStrings = inpStr.split(' ');
+
+ let now: string[] = [];
+ let cnt = 0;
+ spaceSeparatedStrings.forEach((strWithoutSpace) => {
+ const consoleWidth = findWidthInConsole(strWithoutSpace);
+ if (cnt + consoleWidth <= width) {
+ cnt += consoleWidth + 1; // 1 for the space
+ now.push(strWithoutSpace);
+ } else {
+ ret.push(now.join(' '));
+ now = [strWithoutSpace];
+ cnt = consoleWidth + 1;
+ }
+ });
+ ret.push(now.join(' '));
+
+ return ret;
+};
+
+// ("How are you?",10) => ["How are ", "you?"]
+export const biggestWordInSentence = (inpStr: string): number =>
+ inpStr.split(' ').reduce((a, b) => Math.max(a, findWidthInConsole(b)), 0);
diff --git a/src/helpers/tableBuilder/src/utils/table-constants.ts b/src/helpers/tableBuilder/src/utils/table-constants.ts
new file mode 100644
index 0000000..90d7bf9
--- /dev/null
+++ b/src/helpers/tableBuilder/src/utils/table-constants.ts
@@ -0,0 +1,62 @@
+import { ALIGNMENT, COLOR } from '../models/common';
+import { TableStyleDetails } from '../models/internal-table';
+
+export const DEFAULT_COLUMN_LEN = 20;
+
+export const DEFAULT_ROW_SEPARATOR = false;
+
+export const DEFAULT_TABLE_STYLE: TableStyleDetails = {
+ /*
+ Default Style
+ ┌────────────┬─────┬──────┐
+ │ foo │ bar │ baz │
+ │ frobnicate │ bar │ quuz │
+ └────────────┴─────┴──────┘
+ */
+ headerTop: {
+ left: '┌',
+ mid: '┬',
+ right: '┐',
+ other: '─',
+ },
+ headerBottom: {
+ left: '├',
+ mid: '┼',
+ right: '┤',
+ other: '─',
+ },
+ tableBottom: {
+ left: '└',
+ mid: '┴',
+ right: '┘',
+ other: '─',
+ },
+ vertical: '│',
+ rowSeparator: {
+ left: '├',
+ mid: '┼',
+ right: '┤',
+ other: '─',
+ },
+};
+
+export const ALIGNMENTS = ['right', 'left', 'center'];
+
+export const COLORS = [
+ 'red',
+ 'green',
+ 'yellow',
+ 'white',
+ 'blue',
+ 'magenta',
+ 'cyan',
+ 'crimson',
+ 'white_bold',
+ 'reset',
+];
+
+export const DEFAULT_ROW_FONT_COLOR: COLOR = 'white';
+export const DEFAULT_HEADER_FONT_COLOR: COLOR = 'white_bold';
+
+export const DEFAULT_ROW_ALIGNMENT: ALIGNMENT = 'right';
+export const DEFAULT_HEADER_ALIGNMENT: ALIGNMENT = 'center';
diff --git a/src/helpers/tableBuilder/src/utils/table-helpers.ts b/src/helpers/tableBuilder/src/utils/table-helpers.ts
new file mode 100644
index 0000000..51478a3
--- /dev/null
+++ b/src/helpers/tableBuilder/src/utils/table-helpers.ts
@@ -0,0 +1,154 @@
+import { objIfExists } from '../internalTable/input-converter';
+import { COLOR, Dictionary, Row } from '../models/common';
+import { ComputedColumn } from '../models/external-table';
+import { Column } from '../models/internal-table';
+import findWidthInConsole from './console-utils';
+import { biggestWordInSentence, limitWidth } from './string-utils';
+import {
+ DEFAULT_COLUMN_LEN,
+ DEFAULT_ROW_ALIGNMENT,
+ DEFAULT_ROW_SEPARATOR,
+ DEFAULT_HEADER_FONT_COLOR,
+} from './table-constants';
+
+const max = (a: number, b: number) => Math.max(a, b);
+
+// takes any input that is given by user and converts to string
+export const cellText = (text: string | number): string =>
+ text === undefined || text === null ? '' : `${text}`;
+
+export interface RowOptionsRaw {
+ color?: string;
+ separator?: boolean;
+}
+
+export interface RowOptions {
+ color: COLOR;
+ separator: boolean;
+}
+
+export const convertRawRowOptionsToStandard = (
+ options?: RowOptionsRaw
+): RowOptions | undefined => {
+ if (options) {
+ return {
+ color: options.color as COLOR,
+ separator: options.separator || DEFAULT_ROW_SEPARATOR,
+ };
+ }
+ return undefined;
+};
+
+export const createTableHorizontalBorders = (
+ {
+ left,
+ mid,
+ right,
+ other,
+ }: { left: string; mid: string; right: string; other: string },
+ column_lengths: number[]
+) => {
+ // ╚
+ let ret = left;
+
+ // ╚═══════╩═══════════════════════════════════════╩════════╩
+ column_lengths.forEach((len) => {
+ ret += other.repeat(len + 2);
+ ret += mid;
+ });
+
+ // ╚═══════╩═══════════════════════════════════════╩════════
+ ret = ret.slice(0, -mid.length);
+
+ // ╚═══════╩═══════════════════════════════════════╩════════╝
+ ret += right;
+ return ret;
+};
+
+export const createColumFromOnlyName = (name: string): Column => ({
+ name,
+ title: name,
+});
+export const createColumFromComputedColumn = (
+ column: ComputedColumn
+): Column => ({
+ name: column.name,
+ title: column.title || column.name,
+ ...objIfExists('color', column.color as COLOR),
+ ...objIfExists('maxLen', column.maxLen),
+ ...objIfExists('minLen', column.minLen),
+ alignment: column.alignment || DEFAULT_ROW_ALIGNMENT,
+});
+
+export const createRow = (
+ color: COLOR,
+ text: Dictionary,
+ separator: boolean
+): Row => ({
+ color,
+ separator,
+ text,
+});
+
+export const findLenOfColumn = (column: Column, rows: Row[]): number => {
+ const columnId = column.name;
+ const columnTitle = column.title;
+ let length = max(0, column?.minLen || 0);
+
+ if (column.maxLen) {
+ // if customer input is mentioned a max width, lets see if all other can fit here
+ // if others cant fit find the max word length so that at least the table can be printed
+ length = max(
+ length,
+ max(column.maxLen, biggestWordInSentence(columnTitle))
+ );
+ length = rows.reduce(
+ (acc, row) =>
+ max(acc, biggestWordInSentence(cellText(row.text[columnId]))),
+ length
+ );
+ return length;
+ }
+
+ length = max(length, findWidthInConsole(columnTitle));
+
+ rows.forEach((row) => {
+ length = max(length, findWidthInConsole(cellText(row.text[columnId])));
+ });
+
+ return length;
+};
+
+export const renderTableHorizontalBorders = (
+ style: any,
+ column_lengths: number[]
+): string => {
+ const str = createTableHorizontalBorders(style, column_lengths);
+ return str;
+};
+
+export const createHeaderAsRow = (createRowFn: any, columns: Column[]): Row => {
+ const headerColor: COLOR = DEFAULT_HEADER_FONT_COLOR;
+ const row: Row = createRowFn(headerColor, {}, false);
+ columns.forEach((column) => {
+ row.text[column.name] = column.title;
+ });
+ return row;
+};
+
+// { col1: ['How', 'Is', 'Going'], col2: ['I am', 'Tom'], }
+export const getWidthLimitedColumnsArray = (
+ columns: Column[],
+ row: Row
+): { [key: string]: string[] } => {
+ const ret: { [key: string]: string[] } = {};
+
+ columns.forEach((column) => {
+ ret[column.name] = limitWidth(
+ cellText(row.text[column.name]),
+ column.length || DEFAULT_COLUMN_LEN
+ );
+ });
+
+ return ret;
+};
diff --git a/src/lib/display.ts b/src/lib/display.ts
index 4349aa5..2ec19d9 100644
--- a/src/lib/display.ts
+++ b/src/lib/display.ts
@@ -1,5 +1,6 @@
import { Frame } from '../index';
import { table } from 'table';
+import { Table } from '../helpers/tableBuilder';
/**
* getTable returns the data compatible with table.table
@@ -35,6 +36,40 @@ function getTable(
}
/**
+ * displayTable prints the table to the console
+ * @param rowdata the rowdata to be sent to the frame
+ */
+export function displayTable(rowdata: any[][]): void {
+ // Convert row data into object with keys and values, keys are the column names stored in rowdata[0]
+ const headerObject: any = [];
+ rowdata[0].forEach((column) => {
+ headerObject.push({
+ name: column,
+ alignment: 'left',
+ paddingLeft: 2,
+ bold: true,
+ paddingRight: 2
+ });
+ });
+ const table = new Table({
+ columns: headerObject
+ });
+
+ const rowdataObject = rowdata.map((row) => {
+ const rowObject: any = {};
+ row.forEach((value, index) => {
+ rowObject[rowdata[0][index]] = value;
+ });
+ return rowObject;
+ });
+
+ // remove the first row from rowdataObject
+ const rowdataObjectWithoutHeader = rowdataObject.slice(1);
+ table.addRows(rowdataObjectWithoutHeader);
+ table.printTable();
+}
+
+/**
* show prints the frame in console.table format
* @returns the current frame
* @throws Error if the frame is empty
@@ -63,7 +98,7 @@ export function show(this: Frame): void {
numberOfRows - 1
];
const combinedRow = [...firstThreeRows, [...middleRow], ...lastThreeRows];
- console.log(table(getTable(combinedRow, this.columns, indexRow)));
+ displayTable(getTable(combinedRow, this.columns, indexRow));
}
}
}
diff --git a/tests/simple.test.ts b/tests/simple.test.ts
new file mode 100644
index 0000000..fa2167f
--- /dev/null
+++ b/tests/simple.test.ts
@@ -0,0 +1,10 @@
+import { Frame } from '../src/index';
+import { data, header } from './support/people';
+
+const frame = new Frame(data, header);
+
+describe('Print a frame', () => {
+ it('should print a frame', () => {
+ frame.show();
+ });
+});