@oclif/core 3.0.0-beta.9 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/flush.d.ts +3 -0
- package/flush.js +1 -0
- package/handle.js +1 -0
- package/lib/args.d.ts +2 -2
- package/lib/args.js +17 -18
- package/lib/{ux → cli-ux}/action/base.d.ts +19 -21
- package/lib/{ux → cli-ux}/action/base.js +126 -120
- package/lib/{ux → cli-ux}/action/simple.js +25 -30
- package/lib/{ux → cli-ux}/action/spinner.d.ts +9 -7
- package/lib/{ux → cli-ux}/action/spinner.js +45 -37
- package/lib/{ux → cli-ux}/action/spinners.js +187 -187
- package/lib/cli-ux/action/types.d.ts +5 -0
- package/lib/cli-ux/action/types.js +2 -0
- package/lib/{ux → cli-ux}/config.d.ts +5 -5
- package/lib/{ux → cli-ux}/config.js +17 -17
- package/lib/{ux → cli-ux}/exit.js +3 -0
- package/lib/cli-ux/flush.d.ts +1 -0
- package/lib/cli-ux/flush.js +28 -0
- package/lib/cli-ux/index.d.ts +39 -0
- package/lib/{ux → cli-ux}/index.js +74 -88
- package/lib/{ux → cli-ux}/list.js +3 -3
- package/lib/{ux → cli-ux}/prompt.d.ts +3 -3
- package/lib/{ux → cli-ux}/prompt.js +35 -25
- package/lib/{ux → cli-ux}/stream.d.ts +6 -6
- package/lib/{ux → cli-ux}/stream.js +11 -10
- package/lib/cli-ux/styled/index.d.ts +4 -0
- package/lib/cli-ux/styled/index.js +11 -0
- package/lib/{ux → cli-ux}/styled/object.js +7 -9
- package/lib/{ux → cli-ux}/styled/table.d.ts +10 -10
- package/lib/{ux → cli-ux}/styled/table.js +130 -133
- package/lib/{ux → cli-ux}/styled/tree.js +11 -13
- package/lib/cli-ux/wait.js +5 -0
- package/lib/command.d.ts +82 -88
- package/lib/command.js +196 -175
- package/lib/config/config.d.ts +89 -90
- package/lib/config/config.js +466 -566
- package/lib/config/index.d.ts +0 -1
- package/lib/config/index.js +1 -3
- package/lib/config/plugin-loader.d.ts +12 -12
- package/lib/config/plugin-loader.js +72 -56
- package/lib/config/plugin.d.ts +25 -24
- package/lib/config/plugin.js +188 -154
- package/lib/config/ts-node.d.ts +2 -1
- package/lib/config/ts-node.js +71 -58
- package/lib/config/util.d.ts +1 -11
- package/lib/config/util.js +6 -59
- package/lib/errors/config.d.ts +1 -1
- package/lib/errors/config.js +6 -6
- package/lib/errors/errors/cli.d.ts +7 -7
- package/lib/errors/errors/cli.js +20 -16
- package/lib/errors/errors/exit.d.ts +1 -4
- package/lib/errors/errors/exit.js +1 -1
- package/lib/errors/errors/module-load.d.ts +1 -4
- package/lib/errors/errors/module-load.js +1 -1
- package/lib/errors/errors/pretty-print.d.ts +1 -1
- package/lib/errors/errors/pretty-print.js +12 -10
- package/lib/errors/handle.d.ts +12 -2
- package/lib/errors/handle.js +26 -14
- package/lib/errors/index.d.ts +10 -10
- package/lib/errors/index.js +25 -24
- package/lib/errors/logger.d.ts +2 -2
- package/lib/errors/logger.js +14 -13
- package/lib/execute.d.ts +6 -6
- package/lib/execute.js +10 -9
- package/lib/flags.d.ts +103 -32
- package/lib/flags.js +79 -45
- package/lib/help/command.d.ts +16 -14
- package/lib/help/command.js +178 -163
- package/lib/help/docopts.d.ts +5 -5
- package/lib/help/docopts.js +50 -54
- package/lib/help/formatter.d.ts +37 -37
- package/lib/help/formatter.js +66 -55
- package/lib/help/index.d.ts +25 -21
- package/lib/help/index.js +169 -147
- package/lib/help/root.d.ts +1 -1
- package/lib/help/root.js +15 -17
- package/lib/help/util.d.ts +2 -8
- package/lib/help/util.js +8 -28
- package/lib/index.d.ts +19 -20
- package/lib/index.js +37 -43
- package/lib/interfaces/config.d.ts +67 -66
- package/lib/interfaces/errors.d.ts +5 -5
- package/lib/interfaces/help.d.ts +17 -17
- package/lib/interfaces/hooks.d.ts +49 -49
- package/lib/interfaces/index.d.ts +7 -7
- package/lib/interfaces/manifest.d.ts +1 -1
- package/lib/interfaces/parser.d.ts +175 -51
- package/lib/interfaces/pjson.d.ts +41 -41
- package/lib/interfaces/plugin.d.ts +47 -41
- package/lib/interfaces/s3-manifest.d.ts +7 -7
- package/lib/interfaces/topic.d.ts +1 -1
- package/lib/interfaces/ts-config.d.ts +7 -7
- package/lib/main.d.ts +2 -2
- package/lib/main.js +16 -16
- package/lib/module-loader.d.ts +67 -77
- package/lib/module-loader.js +183 -150
- package/lib/parser/errors.d.ts +7 -7
- package/lib/parser/errors.js +29 -22
- package/lib/parser/help.js +5 -5
- package/lib/parser/index.js +2 -2
- package/lib/parser/parse.d.ts +9 -6
- package/lib/parser/parse.js +253 -221
- package/lib/parser/validate.js +53 -33
- package/lib/performance.d.ts +43 -32
- package/lib/performance.js +133 -91
- package/lib/screen.js +2 -2
- package/lib/settings.d.ts +11 -12
- package/lib/settings.js +2 -2
- package/lib/util/aggregate-flags.d.ts +2 -0
- package/lib/util/aggregate-flags.js +13 -0
- package/lib/util/cache-command.d.ts +3 -0
- package/lib/util/cache-command.js +109 -0
- package/lib/util/cache-default-value.d.ts +2 -0
- package/lib/util/cache-default-value.js +28 -0
- package/lib/util/ensure-arg-object.d.ts +12 -0
- package/lib/util/ensure-arg-object.js +14 -0
- package/lib/util/fs.d.ts +7 -0
- package/lib/util/fs.js +54 -0
- package/lib/util/os.d.ts +19 -0
- package/lib/util/os.js +28 -0
- package/lib/{util.d.ts → util/util.d.ts} +7 -16
- package/lib/util/util.js +98 -0
- package/package.json +35 -37
- package/lib/util.js +0 -126
- package/lib/ux/flush.d.ts +0 -1
- package/lib/ux/flush.js +0 -27
- package/lib/ux/index.d.ts +0 -58
- package/lib/ux/styled/index.d.ts +0 -6
- package/lib/ux/styled/index.js +0 -13
- package/lib/ux/styled/json.d.ts +0 -1
- package/lib/ux/styled/json.js +0 -15
- package/lib/ux/wait.js +0 -7
- package/lib/{ux → cli-ux}/action/simple.d.ts +4 -4
- package/lib/{ux → cli-ux}/action/spinners.d.ts +117 -117
- package/lib/{ux → cli-ux}/exit.d.ts +2 -2
- package/lib/{ux → cli-ux}/list.d.ts +0 -0
- package/lib/{ux → cli-ux}/styled/object.d.ts +0 -0
- package/lib/{ux → cli-ux}/styled/progress.d.ts +0 -0
- package/lib/{ux → cli-ux}/styled/progress.js +0 -0
- package/lib/{ux → cli-ux}/styled/tree.d.ts +1 -1
- /package/lib/{ux → cli-ux}/wait.d.ts +0 -0
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
5
|
+
const node_util_1 = require("node:util");
|
|
6
6
|
function styledObject(obj, keys) {
|
|
7
7
|
const output = [];
|
|
8
|
-
const keyLengths = Object.keys(obj).map(key => key.toString().length);
|
|
8
|
+
const keyLengths = Object.keys(obj).map((key) => key.toString().length);
|
|
9
9
|
const maxKeyLength = Math.max(...keyLengths) + 2;
|
|
10
10
|
function pp(obj) {
|
|
11
11
|
if (typeof obj === 'string' || typeof obj === 'number')
|
|
12
12
|
return obj;
|
|
13
13
|
if (typeof obj === 'object') {
|
|
14
14
|
return Object.keys(obj)
|
|
15
|
-
.map(k => k + ': ' +
|
|
15
|
+
.map((k) => k + ': ' + (0, node_util_1.inspect)(obj[k]))
|
|
16
16
|
.join(', ');
|
|
17
17
|
}
|
|
18
|
-
return
|
|
18
|
+
return (0, node_util_1.inspect)(obj);
|
|
19
19
|
}
|
|
20
|
-
const logKeyValue = (key, value) => {
|
|
21
|
-
return `${chalk.blue(key)}:` + ' '.repeat(maxKeyLength - key.length - 1) + pp(value);
|
|
22
|
-
};
|
|
20
|
+
const logKeyValue = (key, value) => `${chalk_1.default.blue(key)}:` + ' '.repeat(maxKeyLength - key.length - 1) + pp(value);
|
|
23
21
|
for (const key of keys || Object.keys(obj).sort()) {
|
|
24
22
|
const value = obj[key];
|
|
25
23
|
if (Array.isArray(value)) {
|
|
@@ -3,13 +3,13 @@ export declare function table<T extends Record<string, unknown>>(data: T[], colu
|
|
|
3
3
|
export declare namespace table {
|
|
4
4
|
export const Flags: {
|
|
5
5
|
columns: Interfaces.OptionFlag<string | undefined>;
|
|
6
|
-
|
|
6
|
+
csv: Interfaces.BooleanFlag<boolean>;
|
|
7
|
+
extended: Interfaces.BooleanFlag<boolean>;
|
|
7
8
|
filter: Interfaces.OptionFlag<string | undefined>;
|
|
8
|
-
|
|
9
|
+
'no-header': Interfaces.BooleanFlag<boolean>;
|
|
10
|
+
'no-truncate': Interfaces.BooleanFlag<boolean>;
|
|
9
11
|
output: Interfaces.OptionFlag<string | undefined>;
|
|
10
|
-
|
|
11
|
-
'no-truncate': Interfaces.Flag<boolean>;
|
|
12
|
-
'no-header': Interfaces.Flag<boolean>;
|
|
12
|
+
sort: Interfaces.OptionFlag<string | undefined>;
|
|
13
13
|
};
|
|
14
14
|
type IFlags = typeof Flags;
|
|
15
15
|
type ExcludeFlags<T, Z> = Pick<T, Exclude<keyof T, Z>>;
|
|
@@ -22,24 +22,24 @@ export declare namespace table {
|
|
|
22
22
|
only: K | K[];
|
|
23
23
|
}): IncludeFlags<IFlags, K>;
|
|
24
24
|
export interface Column<T extends Record<string, unknown>> {
|
|
25
|
-
header: string;
|
|
26
25
|
extended: boolean;
|
|
27
|
-
minWidth: number;
|
|
28
26
|
get(row: T): any;
|
|
27
|
+
header: string;
|
|
28
|
+
minWidth: number;
|
|
29
29
|
}
|
|
30
30
|
export type Columns<T extends Record<string, unknown>> = {
|
|
31
31
|
[key: string]: Partial<Column<T>>;
|
|
32
32
|
};
|
|
33
33
|
export interface Options {
|
|
34
34
|
[key: string]: any;
|
|
35
|
-
sort?: string;
|
|
36
|
-
filter?: string;
|
|
37
35
|
columns?: string;
|
|
38
36
|
extended?: boolean;
|
|
37
|
+
filter?: string;
|
|
38
|
+
'no-header'?: boolean;
|
|
39
39
|
'no-truncate'?: boolean;
|
|
40
40
|
output?: string;
|
|
41
|
-
'no-header'?: boolean;
|
|
42
41
|
printLine?(s: any): any;
|
|
42
|
+
sort?: string;
|
|
43
43
|
}
|
|
44
44
|
export {};
|
|
45
45
|
}
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.table = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const chalk = require("chalk");
|
|
7
|
-
const util_1 = require("../../util");
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
8
6
|
const js_yaml_1 = require("js-yaml");
|
|
9
|
-
const
|
|
7
|
+
const natural_orderby_1 = require("natural-orderby");
|
|
8
|
+
const node_util_1 = require("node:util");
|
|
9
|
+
const slice_ansi_1 = tslib_1.__importDefault(require("slice-ansi"));
|
|
10
|
+
const string_width_1 = tslib_1.__importDefault(require("string-width"));
|
|
11
|
+
const F = tslib_1.__importStar(require("../../flags"));
|
|
12
|
+
const screen_1 = require("../../screen");
|
|
13
|
+
const util_1 = require("../../util/util");
|
|
10
14
|
const stream_1 = require("../stream");
|
|
11
|
-
const sw = require('string-width');
|
|
12
|
-
const { orderBy } = require('natural-orderby');
|
|
13
|
-
const sliceAnsi = require('slice-ansi');
|
|
14
15
|
class Table {
|
|
16
|
+
data;
|
|
17
|
+
columns;
|
|
18
|
+
options;
|
|
15
19
|
constructor(data, columns, options = {}) {
|
|
16
20
|
this.data = data;
|
|
17
21
|
// assign columns
|
|
@@ -20,8 +24,8 @@ class Table {
|
|
|
20
24
|
const extended = col.extended ?? false;
|
|
21
25
|
// turn null and undefined into empty strings by default
|
|
22
26
|
const get = col.get ?? ((row) => row[key] ?? '');
|
|
23
|
-
const header = typeof col.header === 'string' ? col.header : (0, util_1.capitalize)(key.
|
|
24
|
-
const minWidth = Math.max(col.minWidth ?? 0,
|
|
27
|
+
const header = typeof col.header === 'string' ? col.header : (0, util_1.capitalize)(key.replaceAll('_', ' '));
|
|
28
|
+
const minWidth = Math.max(col.minWidth ?? 0, (0, string_width_1.default)(header) + 1);
|
|
25
29
|
return {
|
|
26
30
|
extended,
|
|
27
31
|
get,
|
|
@@ -31,137 +35,59 @@ class Table {
|
|
|
31
35
|
};
|
|
32
36
|
});
|
|
33
37
|
// assign options
|
|
34
|
-
const { columns: cols,
|
|
38
|
+
const { columns: cols, csv, extended, filter, output, printLine, sort, title } = options;
|
|
35
39
|
this.options = {
|
|
36
40
|
columns: cols,
|
|
37
|
-
output: csv ? 'csv' : output,
|
|
38
41
|
extended,
|
|
39
42
|
filter,
|
|
40
43
|
'no-header': options['no-header'] ?? false,
|
|
41
44
|
'no-truncate': options['no-truncate'] ?? false,
|
|
45
|
+
output: csv ? 'csv' : output,
|
|
42
46
|
printLine: printLine ?? ((s) => stream_1.stdout.write(s + '\n')),
|
|
43
47
|
rowStart: ' ',
|
|
44
48
|
sort,
|
|
45
49
|
title,
|
|
46
50
|
};
|
|
47
51
|
}
|
|
48
|
-
display() {
|
|
49
|
-
// build table rows from input array data
|
|
50
|
-
let rows = this.data.map(d => {
|
|
51
|
-
const row = {};
|
|
52
|
-
for (const col of this.columns) {
|
|
53
|
-
let val = col.get(d);
|
|
54
|
-
if (typeof val !== 'string')
|
|
55
|
-
val = (0, util_2.inspect)(val, { breakLength: Number.POSITIVE_INFINITY });
|
|
56
|
-
row[col.key] = val;
|
|
57
|
-
}
|
|
58
|
-
return row;
|
|
59
|
-
});
|
|
60
|
-
// filter rows
|
|
61
|
-
if (this.options.filter) {
|
|
62
|
-
/* eslint-disable-next-line prefer-const */
|
|
63
|
-
let [header, regex] = this.options.filter.split('=');
|
|
64
|
-
const isNot = header[0] === '-';
|
|
65
|
-
if (isNot)
|
|
66
|
-
header = header.slice(1);
|
|
67
|
-
const col = this.findColumnFromHeader(header);
|
|
68
|
-
if (!col || !regex)
|
|
69
|
-
throw new Error('Filter flag has an invalid value');
|
|
70
|
-
rows = rows.filter((d) => {
|
|
71
|
-
const re = new RegExp(regex);
|
|
72
|
-
const val = d[col.key];
|
|
73
|
-
const match = val.match(re);
|
|
74
|
-
return isNot ? !match : match;
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
// sort rows
|
|
78
|
-
if (this.options.sort) {
|
|
79
|
-
const sorters = this.options.sort.split(',');
|
|
80
|
-
const sortHeaders = sorters.map(k => k[0] === '-' ? k.slice(1) : k);
|
|
81
|
-
const sortKeys = this.filterColumnsFromHeaders(sortHeaders).map(c => {
|
|
82
|
-
return ((v) => v[c.key]);
|
|
83
|
-
});
|
|
84
|
-
const sortKeysOrder = sorters.map(k => k[0] === '-' ? 'desc' : 'asc');
|
|
85
|
-
rows = orderBy(rows, sortKeys, sortKeysOrder);
|
|
86
|
-
}
|
|
87
|
-
// and filter columns
|
|
88
|
-
if (this.options.columns) {
|
|
89
|
-
const filters = this.options.columns.split(',');
|
|
90
|
-
this.columns = this.filterColumnsFromHeaders(filters);
|
|
91
|
-
}
|
|
92
|
-
else if (!this.options.extended) {
|
|
93
|
-
// show extented columns/properties
|
|
94
|
-
this.columns = this.columns.filter(c => !c.extended);
|
|
95
|
-
}
|
|
96
|
-
this.data = rows;
|
|
97
|
-
switch (this.options.output) {
|
|
98
|
-
case 'csv':
|
|
99
|
-
this.outputCSV();
|
|
100
|
-
break;
|
|
101
|
-
case 'json':
|
|
102
|
-
this.outputJSON();
|
|
103
|
-
break;
|
|
104
|
-
case 'yaml':
|
|
105
|
-
this.outputYAML();
|
|
106
|
-
break;
|
|
107
|
-
default:
|
|
108
|
-
this.outputTable();
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
findColumnFromHeader(header) {
|
|
112
|
-
return this.columns.find(c => c.header.toLowerCase() === header.toLowerCase());
|
|
113
|
-
}
|
|
114
52
|
filterColumnsFromHeaders(filters) {
|
|
115
53
|
// unique
|
|
116
|
-
filters = [...
|
|
54
|
+
filters = [...new Set(filters)];
|
|
117
55
|
const cols = [];
|
|
118
56
|
for (const f of filters) {
|
|
119
|
-
const c = this.columns.find(c => c.header.toLowerCase() === f.toLowerCase());
|
|
57
|
+
const c = this.columns.find((c) => c.header.toLowerCase() === f.toLowerCase());
|
|
120
58
|
if (c)
|
|
121
59
|
cols.push(c);
|
|
122
60
|
}
|
|
123
61
|
return cols;
|
|
124
62
|
}
|
|
63
|
+
findColumnFromHeader(header) {
|
|
64
|
+
return this.columns.find((c) => c.header.toLowerCase() === header.toLowerCase());
|
|
65
|
+
}
|
|
125
66
|
getCSVRow(d) {
|
|
126
|
-
const values = this.columns.map(col => d[col.key] || '');
|
|
67
|
+
const values = this.columns.map((col) => d[col.key] || '');
|
|
127
68
|
const lineToBeEscaped = values.find((e) => e.includes('"') || e.includes('\n') || e.includes('\r\n') || e.includes('\r') || e.includes(','));
|
|
128
|
-
return values.map(e => lineToBeEscaped ? `"${e.replace('"', '""')}"` : e);
|
|
129
|
-
}
|
|
130
|
-
resolveColumnsToObjectArray() {
|
|
131
|
-
const { data, columns } = this;
|
|
132
|
-
return data.map((d) => {
|
|
133
|
-
// eslint-disable-next-line unicorn/prefer-object-from-entries
|
|
134
|
-
return columns.reduce((obj, col) => {
|
|
135
|
-
return {
|
|
136
|
-
...obj,
|
|
137
|
-
[col.key]: d[col.key] ?? '',
|
|
138
|
-
};
|
|
139
|
-
}, {});
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
outputJSON() {
|
|
143
|
-
this.options.printLine(JSON.stringify(this.resolveColumnsToObjectArray(), undefined, 2));
|
|
144
|
-
}
|
|
145
|
-
outputYAML() {
|
|
146
|
-
this.options.printLine((0, js_yaml_1.safeDump)(this.resolveColumnsToObjectArray()));
|
|
69
|
+
return values.map((e) => (lineToBeEscaped ? `"${e.replace('"', '""')}"` : e));
|
|
147
70
|
}
|
|
148
71
|
outputCSV() {
|
|
149
|
-
const {
|
|
72
|
+
const { columns, data, options } = this;
|
|
150
73
|
if (!options['no-header']) {
|
|
151
|
-
options.printLine(columns.map(c => c.header).join(','));
|
|
74
|
+
options.printLine(columns.map((c) => c.header).join(','));
|
|
152
75
|
}
|
|
153
76
|
for (const d of data) {
|
|
154
77
|
const row = this.getCSVRow(d);
|
|
155
78
|
options.printLine(row.join(','));
|
|
156
79
|
}
|
|
157
80
|
}
|
|
81
|
+
outputJSON() {
|
|
82
|
+
this.options.printLine(JSON.stringify(this.resolveColumnsToObjectArray(), undefined, 2));
|
|
83
|
+
}
|
|
158
84
|
outputTable() {
|
|
159
85
|
const { data, options } = this;
|
|
160
86
|
// column truncation
|
|
161
87
|
//
|
|
162
88
|
// find max width for each column
|
|
163
|
-
const columns = this.columns.map(c => {
|
|
164
|
-
const maxWidth = Math.max(
|
|
89
|
+
const columns = this.columns.map((c) => {
|
|
90
|
+
const maxWidth = Math.max((0, string_width_1.default)('.'.padEnd(c.minWidth - 1)), (0, string_width_1.default)(c.header), getWidestColumnWith(data, c.key)) + 1;
|
|
165
91
|
return {
|
|
166
92
|
...c,
|
|
167
93
|
maxWidth,
|
|
@@ -176,7 +102,7 @@ class Table {
|
|
|
176
102
|
if (options['no-truncate'] || (!stream_1.stdout.isTTY && !process.env.CLI_UX_SKIP_TTY_CHECK))
|
|
177
103
|
return;
|
|
178
104
|
// don't shorten if there is enough screen width
|
|
179
|
-
const dataMaxWidth = (0, util_1.sumBy)(columns, c => c.width);
|
|
105
|
+
const dataMaxWidth = (0, util_1.sumBy)(columns, (c) => c.width);
|
|
180
106
|
const overWidth = dataMaxWidth - maxWidth;
|
|
181
107
|
if (overWidth <= 0)
|
|
182
108
|
return;
|
|
@@ -187,16 +113,18 @@ class Table {
|
|
|
187
113
|
// if sum(minWidth's) is greater than term width
|
|
188
114
|
// nothing can be done so
|
|
189
115
|
// display all as minWidth
|
|
190
|
-
const dataMinWidth = (0, util_1.sumBy)(columns, c => c.minWidth);
|
|
116
|
+
const dataMinWidth = (0, util_1.sumBy)(columns, (c) => c.minWidth);
|
|
191
117
|
if (dataMinWidth >= maxWidth)
|
|
192
118
|
return;
|
|
193
119
|
// some wiggle room left, add it back to "needy" columns
|
|
194
120
|
let wiggleRoom = maxWidth - dataMinWidth;
|
|
195
|
-
const needyCols = columns
|
|
121
|
+
const needyCols = columns
|
|
122
|
+
.map((c) => ({ key: c.key, needs: c.maxWidth - c.width }))
|
|
123
|
+
.sort((a, b) => a.needs - b.needs);
|
|
196
124
|
for (const { key, needs } of needyCols) {
|
|
197
125
|
if (!needs)
|
|
198
126
|
continue;
|
|
199
|
-
const col = columns.find(c => key === c.key);
|
|
127
|
+
const col = columns.find((c) => key === c.key);
|
|
200
128
|
if (!col)
|
|
201
129
|
continue;
|
|
202
130
|
if (wiggleRoom > needs) {
|
|
@@ -224,14 +152,14 @@ class Table {
|
|
|
224
152
|
const header = col.header;
|
|
225
153
|
headers += header.padEnd(col.width);
|
|
226
154
|
}
|
|
227
|
-
options.printLine(
|
|
155
|
+
options.printLine(chalk_1.default.bold(headers));
|
|
228
156
|
// print header dividers
|
|
229
157
|
let dividers = options.rowStart;
|
|
230
158
|
for (const col of columns) {
|
|
231
159
|
const divider = ''.padEnd(col.width - 1, '─') + ' ';
|
|
232
160
|
dividers += divider.padEnd(col.width);
|
|
233
161
|
}
|
|
234
|
-
options.printLine(
|
|
162
|
+
options.printLine(chalk_1.default.bold(dividers));
|
|
235
163
|
}
|
|
236
164
|
// print rows
|
|
237
165
|
for (const row of data) {
|
|
@@ -255,16 +183,16 @@ class Table {
|
|
|
255
183
|
const width = col.width;
|
|
256
184
|
let d = row[col.key];
|
|
257
185
|
d = d.split('\n')[i] || '';
|
|
258
|
-
const visualWidth =
|
|
259
|
-
const colorWidth =
|
|
186
|
+
const visualWidth = (0, string_width_1.default)(d);
|
|
187
|
+
const colorWidth = d.length - visualWidth;
|
|
260
188
|
let cell = d.padEnd(width + colorWidth);
|
|
261
|
-
if (
|
|
189
|
+
if (cell.length - colorWidth > width || visualWidth === width) {
|
|
262
190
|
// truncate the cell, preserving ANSI escape sequences, and keeping
|
|
263
191
|
// into account the width of fullwidth unicode characters
|
|
264
|
-
cell =
|
|
192
|
+
cell = (0, slice_ansi_1.default)(cell, 0, width - 2) + '… ';
|
|
265
193
|
// pad with spaces; this is necessary in case the original string
|
|
266
194
|
// contained fullwidth characters which cannot be split
|
|
267
|
-
cell += ' '.repeat(width -
|
|
195
|
+
cell += ' '.repeat(width - (0, string_width_1.default)(cell));
|
|
268
196
|
}
|
|
269
197
|
l += cell;
|
|
270
198
|
}
|
|
@@ -272,6 +200,77 @@ class Table {
|
|
|
272
200
|
}
|
|
273
201
|
}
|
|
274
202
|
}
|
|
203
|
+
outputYAML() {
|
|
204
|
+
this.options.printLine((0, js_yaml_1.safeDump)(this.resolveColumnsToObjectArray()));
|
|
205
|
+
}
|
|
206
|
+
resolveColumnsToObjectArray() {
|
|
207
|
+
const { columns, data } = this;
|
|
208
|
+
return data.map((d) => Object.fromEntries(columns.map((col) => [col.key, d[col.key] ?? ''])));
|
|
209
|
+
}
|
|
210
|
+
display() {
|
|
211
|
+
// build table rows from input array data
|
|
212
|
+
let rows = this.data.map((d) => {
|
|
213
|
+
const row = {};
|
|
214
|
+
for (const col of this.columns) {
|
|
215
|
+
let val = col.get(d);
|
|
216
|
+
if (typeof val !== 'string')
|
|
217
|
+
val = (0, node_util_1.inspect)(val, { breakLength: Number.POSITIVE_INFINITY });
|
|
218
|
+
row[col.key] = val;
|
|
219
|
+
}
|
|
220
|
+
return row;
|
|
221
|
+
});
|
|
222
|
+
// filter rows
|
|
223
|
+
if (this.options.filter) {
|
|
224
|
+
let [header, regex] = this.options.filter.split('=');
|
|
225
|
+
const isNot = header[0] === '-';
|
|
226
|
+
if (isNot)
|
|
227
|
+
header = header.slice(1);
|
|
228
|
+
const col = this.findColumnFromHeader(header);
|
|
229
|
+
if (!col || !regex)
|
|
230
|
+
throw new Error('Filter flag has an invalid value');
|
|
231
|
+
rows = rows.filter((d) => {
|
|
232
|
+
const re = new RegExp(regex);
|
|
233
|
+
const val = d[col.key];
|
|
234
|
+
const match = val.match(re);
|
|
235
|
+
return isNot ? !match : match;
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
// sort rows
|
|
239
|
+
if (this.options.sort) {
|
|
240
|
+
const sorters = this.options.sort.split(',');
|
|
241
|
+
const sortHeaders = sorters.map((k) => (k[0] === '-' ? k.slice(1) : k));
|
|
242
|
+
const sortKeys = this.filterColumnsFromHeaders(sortHeaders).map((c) => (v) => v[c.key]);
|
|
243
|
+
const sortKeysOrder = sorters.map((k) => (k[0] === '-' ? 'desc' : 'asc'));
|
|
244
|
+
rows = (0, natural_orderby_1.orderBy)(rows, sortKeys, sortKeysOrder);
|
|
245
|
+
}
|
|
246
|
+
// and filter columns
|
|
247
|
+
if (this.options.columns) {
|
|
248
|
+
const filters = this.options.columns.split(',');
|
|
249
|
+
this.columns = this.filterColumnsFromHeaders(filters);
|
|
250
|
+
}
|
|
251
|
+
else if (!this.options.extended) {
|
|
252
|
+
// show extented columns/properties
|
|
253
|
+
this.columns = this.columns.filter((c) => !c.extended);
|
|
254
|
+
}
|
|
255
|
+
this.data = rows;
|
|
256
|
+
switch (this.options.output) {
|
|
257
|
+
case 'csv': {
|
|
258
|
+
this.outputCSV();
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
case 'json': {
|
|
262
|
+
this.outputJSON();
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
case 'yaml': {
|
|
266
|
+
this.outputYAML();
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
default: {
|
|
270
|
+
this.outputTable();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
275
274
|
}
|
|
276
275
|
function table(data, columns, options = {}) {
|
|
277
276
|
new Table(data, columns, options).display();
|
|
@@ -279,20 +278,19 @@ function table(data, columns, options = {}) {
|
|
|
279
278
|
exports.table = table;
|
|
280
279
|
(function (table) {
|
|
281
280
|
table.Flags = {
|
|
282
|
-
columns: F.string({
|
|
283
|
-
|
|
281
|
+
columns: F.string({ description: 'only show provided columns (comma-separated)', exclusive: ['extended'] }),
|
|
282
|
+
csv: F.boolean({ description: 'output is csv format [alias: --output=csv]', exclusive: ['no-truncate'] }),
|
|
283
|
+
extended: F.boolean({ char: 'x', description: 'show extra columns', exclusive: ['columns'] }),
|
|
284
284
|
filter: F.string({ description: 'filter property by partial string matching, ex: name=foo' }),
|
|
285
|
-
|
|
285
|
+
'no-header': F.boolean({ description: 'hide table header from output', exclusive: ['csv'] }),
|
|
286
|
+
'no-truncate': F.boolean({ description: 'do not truncate output to fit screen', exclusive: ['csv'] }),
|
|
286
287
|
output: F.string({
|
|
287
|
-
exclusive: ['no-truncate', 'csv'],
|
|
288
288
|
description: 'output in a more machine friendly format',
|
|
289
|
+
exclusive: ['no-truncate', 'csv'],
|
|
289
290
|
options: ['csv', 'json', 'yaml'],
|
|
290
291
|
}),
|
|
291
|
-
|
|
292
|
-
'no-truncate': F.boolean({ exclusive: ['csv'], description: 'do not truncate output to fit screen' }),
|
|
293
|
-
'no-header': F.boolean({ exclusive: ['csv'], description: 'hide table header from output' }),
|
|
292
|
+
sort: F.string({ description: "property to sort by (prepend '-' for descending)" }),
|
|
294
293
|
};
|
|
295
|
-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
296
294
|
function flags(opts) {
|
|
297
295
|
if (opts) {
|
|
298
296
|
const f = {};
|
|
@@ -300,6 +298,7 @@ exports.table = table;
|
|
|
300
298
|
const e = (opts.except && typeof opts.except === 'string' ? [opts.except] : opts.except) || [];
|
|
301
299
|
for (const key of o) {
|
|
302
300
|
if (!e.includes(key)) {
|
|
301
|
+
;
|
|
303
302
|
f[key] = table.Flags[key];
|
|
304
303
|
}
|
|
305
304
|
}
|
|
@@ -308,13 +307,11 @@ exports.table = table;
|
|
|
308
307
|
return table.Flags;
|
|
309
308
|
}
|
|
310
309
|
table.flags = flags;
|
|
311
|
-
})(table
|
|
312
|
-
const getWidestColumnWith = (data, columnKey) => {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}, 0);
|
|
320
|
-
};
|
|
310
|
+
})(table || (exports.table = table = {}));
|
|
311
|
+
const getWidestColumnWith = (data, columnKey) => data.reduce((previous, current) => {
|
|
312
|
+
const d = current[columnKey];
|
|
313
|
+
// convert multi-line cell to single longest line
|
|
314
|
+
// for width calculations
|
|
315
|
+
const manyLines = d.split('\n');
|
|
316
|
+
return Math.max(previous, manyLines.length > 1 ? Math.max(...manyLines.map((r) => (0, string_width_1.default)(r))) : (0, string_width_1.default)(d));
|
|
317
|
+
}, 0);
|
|
@@ -3,8 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Tree = void 0;
|
|
4
4
|
const treeify = require('object-treeify');
|
|
5
5
|
class Tree {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
nodes = {};
|
|
7
|
+
display(logger = console.log) {
|
|
8
|
+
const addNodes = function (nodes) {
|
|
9
|
+
const tree = {};
|
|
10
|
+
for (const p of Object.keys(nodes)) {
|
|
11
|
+
tree[p] = addNodes(nodes[p].nodes);
|
|
12
|
+
}
|
|
13
|
+
return tree;
|
|
14
|
+
};
|
|
15
|
+
const tree = addNodes(this.nodes);
|
|
16
|
+
logger(treeify(tree));
|
|
8
17
|
}
|
|
9
18
|
insert(child, value = new Tree()) {
|
|
10
19
|
this.nodes[child] = value;
|
|
@@ -20,17 +29,6 @@ class Tree {
|
|
|
20
29
|
return c;
|
|
21
30
|
}
|
|
22
31
|
}
|
|
23
|
-
display(logger = console.log) {
|
|
24
|
-
const addNodes = function (nodes) {
|
|
25
|
-
const tree = {};
|
|
26
|
-
for (const p of Object.keys(nodes)) {
|
|
27
|
-
tree[p] = addNodes(nodes[p].nodes);
|
|
28
|
-
}
|
|
29
|
-
return tree;
|
|
30
|
-
};
|
|
31
|
-
const tree = addNodes(this.nodes);
|
|
32
|
-
logger(treeify(tree));
|
|
33
|
-
}
|
|
34
32
|
}
|
|
35
33
|
exports.Tree = Tree;
|
|
36
34
|
function tree() {
|