@oclif/table 0.4.14 → 0.5.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 +264 -6
- package/lib/table.d.ts +3 -2
- package/lib/table.js +14 -10
- package/lib/types.d.ts +8 -2
- package/lib/utils.d.ts +1 -1
- package/lib/utils.js +5 -0
- package/package.json +8 -6
package/README.md
CHANGED
|
@@ -4,20 +4,278 @@
|
|
|
4
4
|
[](https://npmjs.org/package/@oclif/table)
|
|
5
5
|
[](https://github.com/oclif/table/blob/main/LICENSE)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
### Description
|
|
8
8
|
|
|
9
|
-
Print tables to the terminal using [
|
|
9
|
+
Print beautiful, flexible tables to the terminal using [Ink](https://www.npmjs.com/package/ink). This library powers many oclif/Salesforce CLIs and is built for real-world, production output: wide columns, multi-line cells, smart wrapping/truncation, theming, and great CI behavior.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### Features
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
- Rich rendering via Ink with graceful fallback to plain text in CI
|
|
14
|
+
- Automatic column sizing with max/explicit width support (including percentages)
|
|
15
|
+
- Per-column alignment, padding, and overflow control (wrap, truncate, middle/start/end)
|
|
16
|
+
- Header formatting with `change-case` presets or custom function
|
|
17
|
+
- Multiple border styles (outline, headers-only, vertical/horizontal, none, and more)
|
|
18
|
+
- Sort and filter data, optionally per-column
|
|
19
|
+
- Print multiple tables side-by-side or stacked with layout controls
|
|
20
|
+
- Return a string (`makeTable`) or print directly (`printTable`/`printTables`)
|
|
21
|
+
- TypeScript-first API with excellent types
|
|
14
22
|
|
|
15
|
-
|
|
23
|
+
---
|
|
16
24
|
|
|
25
|
+
### Requirements
|
|
26
|
+
|
|
27
|
+
- Node.js >= 18
|
|
28
|
+
- ESM only (this package has `"type": "module"`). Use `import`, not `require`.
|
|
29
|
+
|
|
30
|
+
### Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @oclif/table
|
|
34
|
+
# or
|
|
35
|
+
yarn add @oclif/table
|
|
36
|
+
# or
|
|
37
|
+
pnpm add @oclif/table
|
|
38
|
+
# or
|
|
39
|
+
bun add @oclif/table
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Quick start
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
import {printTable} from '@oclif/table'
|
|
46
|
+
|
|
47
|
+
const data = [
|
|
48
|
+
{name: 'Alice', role: 'Engineer', notes: 'Loves distributed systems'},
|
|
49
|
+
{name: 'Bob', role: 'Designer', notes: 'Enjoys typography and UI'},
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
printTable({
|
|
53
|
+
title: 'Team',
|
|
54
|
+
data,
|
|
55
|
+
columns: [
|
|
56
|
+
{key: 'name', width: 16},
|
|
57
|
+
{key: 'role', width: 14, horizontalAlignment: 'center'},
|
|
58
|
+
{key: 'notes', overflow: 'wrap'},
|
|
59
|
+
],
|
|
60
|
+
})
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
To generate a string instead of printing to stdout:
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
import {makeTable} from '@oclif/table'
|
|
67
|
+
|
|
68
|
+
const output = makeTable({data, columns: ['name', 'role', 'notes']})
|
|
69
|
+
// do something with `output`
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
To print multiple tables in one layout:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
import {printTables} from '@oclif/table'
|
|
76
|
+
|
|
77
|
+
printTables(
|
|
78
|
+
[
|
|
79
|
+
{title: 'Developers', data, columns: ['name', 'role']},
|
|
80
|
+
{title: 'Notes', data, columns: ['notes']},
|
|
81
|
+
],
|
|
82
|
+
{direction: 'row', columnGap: 4, margin: 1},
|
|
83
|
+
)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
### API
|
|
89
|
+
|
|
90
|
+
- `printTable(options)` — renders a single table to stdout.
|
|
91
|
+
- `makeTable(options): string` — renders a single table and returns the output string.
|
|
92
|
+
- `printTables(tables, options?)` — renders multiple tables with layout controls.
|
|
93
|
+
|
|
94
|
+
All three accept the same `TableOptions<T>` (documented below). `printTables` accepts an array of `TableOptions` plus optional container layout props.
|
|
95
|
+
|
|
96
|
+
#### TypeScript
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import type {TableOptions} from '@oclif/table'
|
|
100
|
+
|
|
101
|
+
type Row = {name: string; age: number}
|
|
102
|
+
const opts: TableOptions<Row> = {
|
|
103
|
+
data: [{name: 'Ada', age: 36}],
|
|
104
|
+
columns: [
|
|
105
|
+
{key: 'name', name: 'Full Name'},
|
|
106
|
+
{key: 'age', horizontalAlignment: 'right'},
|
|
107
|
+
],
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### Options reference
|
|
114
|
+
|
|
115
|
+
Below are the most important options with defaults and behavior. See examples in `./examples` for more patterns.
|
|
116
|
+
|
|
117
|
+
- `data` (required): array of rows, each a plain object.
|
|
118
|
+
- `columns`: list of keys or objects describing each column.
|
|
119
|
+
- String form: `'name'` (uses key as header)
|
|
120
|
+
- Object form: `{ key, name?, width?, padding?, overflow?, horizontalAlignment?, verticalAlignment? }`
|
|
121
|
+
- `name`: header label (defaults to key or formatted with `headerOptions.formatter`)
|
|
122
|
+
- `width`: number of characters or percentage string like `'50%'`
|
|
123
|
+
- `padding`: spaces added on both sides (default: table `padding`)
|
|
124
|
+
- `overflow`: `'wrap' | 'truncate' | 'truncate-start' | 'truncate-middle' | 'truncate-end'`
|
|
125
|
+
- `horizontalAlignment`: `'left' | 'center' | 'right'`
|
|
126
|
+
- `verticalAlignment`: `'top' | 'center' | 'bottom'`
|
|
127
|
+
|
|
128
|
+
- `padding` (number): cell padding for all columns. Default: `1`.
|
|
129
|
+
|
|
130
|
+
- `maxWidth` (number | percentage | 'none'): maximum table width. Defaults to terminal width.
|
|
131
|
+
- When the natural table width exceeds `maxWidth`, columns shrink and content wraps/truncates based on `overflow`.
|
|
132
|
+
- Use `'none'` to allow unlimited width (useful for very wide outputs; users can resize their terminals).
|
|
133
|
+
|
|
134
|
+
- `width` (number | percentage): exact table width. Overrides `maxWidth`. If wider than the natural width, columns expand evenly.
|
|
135
|
+
|
|
136
|
+
- `overflow`: cell overflow behavior. Default: `'truncate'`.
|
|
137
|
+
- `'wrap'` wraps long content
|
|
138
|
+
- `'truncate'` truncates the end
|
|
139
|
+
- `'truncate-start' | 'truncate-middle' | 'truncate-end'` choose truncation position
|
|
140
|
+
|
|
141
|
+
- `headerOptions`: style options for headers.
|
|
142
|
+
- `formatter`: either a function `(header: string) => string` or a `change-case` preset name:
|
|
143
|
+
`'camelCase' | 'capitalCase' | 'constantCase' | 'kebabCase' | 'pascalCase' | 'sentenceCase' | 'snakeCase'`
|
|
144
|
+
- Styling keys (also supported by `titleOptions`):
|
|
145
|
+
- `color`, `backgroundColor` (named color, hex `#rrggbb`, or `rgb(r,g,b)`)
|
|
146
|
+
- `bold`, `dimColor`, `italic`, `underline`, `strikethrough`, `inverse`
|
|
147
|
+
- Default header style is bold blue (unless `noStyle: true`).
|
|
148
|
+
|
|
149
|
+
- `borderStyle`: border preset. Default: `'all'`.
|
|
150
|
+
- Available: `'all' | 'headers-only' | 'headers-only-with-outline' | 'headers-only-with-underline' | 'horizontal' | 'horizontal-with-outline' | 'none' | 'outline' | 'vertical' | 'vertical-rows-with-outline' | 'vertical-with-outline'`
|
|
151
|
+
|
|
152
|
+
- `borderColor`: optional border color. When unset, the terminal's default color is used.
|
|
153
|
+
|
|
154
|
+
- `horizontalAlignment`: default column alignment. Default: `'left'`.
|
|
155
|
+
|
|
156
|
+
- `verticalAlignment`: default vertical alignment within cells. Default: `'top'`.
|
|
157
|
+
|
|
158
|
+
- `filter(row)`: predicate to include/exclude rows.
|
|
159
|
+
|
|
160
|
+
- `sort`: object mapping keys to `'asc' | 'desc' | (a,b)=>number`. Keys order defines multi-column priority.
|
|
161
|
+
|
|
162
|
+
- `title`: optional string printed above the table.
|
|
163
|
+
|
|
164
|
+
- `titleOptions`: style options for the title (same keys as `headerOptions` except `formatter`).
|
|
165
|
+
|
|
166
|
+
- `trimWhitespace`: when wrapping text, trim whitespace at line boundaries. Default: `true`.
|
|
167
|
+
|
|
168
|
+
- `noStyle`: disable all styling. Also strips ANSI color codes from your cell content for accurate width calculation.
|
|
169
|
+
|
|
170
|
+
#### Container options (for `printTables`)
|
|
171
|
+
|
|
172
|
+
`printTables(tables, containerOptions)` accepts:
|
|
173
|
+
|
|
174
|
+
- `direction`: `'row' | 'column'` (default `'row'`)
|
|
175
|
+
- `columnGap`, `rowGap`: spacing between tables
|
|
176
|
+
- `alignItems`: `'flex-start' | 'center' | 'flex-end'`
|
|
177
|
+
- `margin`, `marginLeft`, `marginRight`, `marginTop`, `marginBottom`
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
### Behavior and environment variables
|
|
182
|
+
|
|
183
|
+
- Terminal width detection: by default we use your terminal width. Override with `OCLIF_TABLE_COLUMN_OVERRIDE`.
|
|
184
|
+
- Example: `OCLIF_TABLE_COLUMN_OVERRIDE=120 node app.js`
|
|
185
|
+
|
|
186
|
+
- CI-safe output: in CI environments, we automatically fall back to a plain-text renderer (no Ink) for stability.
|
|
187
|
+
- To force Ink rendering in CI, set `OCLIF_TABLE_SKIP_CI_CHECK=1`.
|
|
188
|
+
|
|
189
|
+
- Very large data: by default, datasets with 10,000+ rows use the plain-text renderer to avoid memory issues.
|
|
190
|
+
- Override with `OCLIF_TABLE_LIMIT=<number>` (Salesforce CLIs may also honor `SF_TABLE_LIMIT`).
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### Advanced examples
|
|
195
|
+
|
|
196
|
+
Header formatting with `change-case`:
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
import {printTable} from '@oclif/table'
|
|
200
|
+
|
|
201
|
+
printTable({
|
|
202
|
+
data: [{first_name: 'Ada', last_name: 'Lovelace'}],
|
|
203
|
+
columns: ['first_name', 'last_name'],
|
|
204
|
+
headerOptions: {formatter: 'capitalCase'},
|
|
205
|
+
})
|
|
17
206
|
```
|
|
207
|
+
|
|
208
|
+
Per-column sizing and overflow:
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
printTable({
|
|
212
|
+
data: [{name: 'A very very long name', notes: 'Multi-line\ncontent supported'}],
|
|
213
|
+
maxWidth: '80%',
|
|
214
|
+
columns: [
|
|
215
|
+
{key: 'name', width: 20, overflow: 'truncate-middle'},
|
|
216
|
+
{key: 'notes', overflow: 'wrap', horizontalAlignment: 'right'},
|
|
217
|
+
],
|
|
218
|
+
})
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Switching borders and colors:
|
|
222
|
+
|
|
223
|
+
```js
|
|
224
|
+
printTable({
|
|
225
|
+
title: 'Inventory',
|
|
226
|
+
titleOptions: {bold: true, color: 'cyan'},
|
|
227
|
+
data: [{item: 'Widget', qty: 10}],
|
|
228
|
+
columns: ['item', {key: 'qty', horizontalAlignment: 'right'}],
|
|
229
|
+
borderStyle: 'vertical-with-outline',
|
|
230
|
+
borderColor: 'green',
|
|
231
|
+
})
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
### Examples directory
|
|
237
|
+
|
|
238
|
+
This repo contains many runnable examples in `./examples` (including edge cases like very wide/very tall tables). Run any with:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
18
241
|
tsx examples/basic.ts
|
|
19
242
|
```
|
|
20
243
|
|
|
21
|
-
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
### Testing
|
|
247
|
+
|
|
248
|
+
This package includes snapshot tests for all examples to ensure consistent output across different environments.
|
|
249
|
+
|
|
250
|
+
#### Running tests
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# Run all tests (including snapshot tests)
|
|
254
|
+
yarn test
|
|
255
|
+
|
|
256
|
+
# Run only snapshot tests
|
|
257
|
+
yarn test:examples
|
|
258
|
+
|
|
259
|
+
# Update snapshots after intentional changes
|
|
260
|
+
yarn test:examples:update
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### How snapshot testing works
|
|
264
|
+
|
|
265
|
+
Examples are executed in an isolated child process with:
|
|
266
|
+
|
|
267
|
+
- Fixed terminal width (`OCLIF_TABLE_COLUMN_OVERRIDE=120`)
|
|
268
|
+
- Disabled CI detection unless an example sets it
|
|
269
|
+
- ESM loader for TypeScript (`ts-node/esm`)
|
|
270
|
+
|
|
271
|
+
Snapshots live in `test/__snapshots__/examples/*.txt` and mirror the `examples` directory structure.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
### Contributing
|
|
22
276
|
|
|
23
277
|
See the [contributing guide](./CONRTIBUTING.md).
|
|
278
|
+
|
|
279
|
+
### License
|
|
280
|
+
|
|
281
|
+
MIT © Salesforce
|
package/lib/table.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { CellProps, ContainerProps, HorizontalAlignment, Overflow, TableOptions } from './types.js';
|
|
3
|
-
export declare function formatTextWithMargins({ horizontalAlignment, overflow, padding, trimWhitespace, value, width }: {
|
|
3
|
+
export declare function formatTextWithMargins({ horizontalAlignment, overflow, padding, trimWhitespace, value, width, }: {
|
|
4
4
|
overflow: Overflow;
|
|
5
5
|
value: unknown;
|
|
6
6
|
width: number;
|
|
@@ -50,7 +50,8 @@ export declare function makeTable<T extends Record<string, unknown>>(options: Ta
|
|
|
50
50
|
* @template T - An array of records where each record represents a table.
|
|
51
51
|
* @param {Object.<keyof T, TableOptions<T[keyof T]>>} tables - An object containing table options for each table.
|
|
52
52
|
* @param {Omit<ContainerProps, 'children'>} [options] - Optional container properties excluding 'children'.
|
|
53
|
-
* @throws {Error} Throws an error if the total number of rows across all tables exceeds
|
|
53
|
+
* @throws {Error} Throws an error if the total number of rows across all tables exceeds 10,000.
|
|
54
|
+
* @throws {Error} Throws an error if any of the tables have `maxWidth: "none"`.
|
|
54
55
|
*/
|
|
55
56
|
export declare function printTables<T extends Record<string, unknown>[]>(tables: {
|
|
56
57
|
[P in keyof T]: TableOptions<T[P]>;
|
package/lib/table.js
CHANGED
|
@@ -34,7 +34,7 @@ function determineTruncatePosition(overflow) {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
export function formatTextWithMargins({ horizontalAlignment, overflow, padding, trimWhitespace = true, value, width }) {
|
|
37
|
+
export function formatTextWithMargins({ horizontalAlignment, overflow, padding, trimWhitespace = true, value, width, }) {
|
|
38
38
|
function calculateMargins(spaces) {
|
|
39
39
|
let marginLeft;
|
|
40
40
|
let marginRight;
|
|
@@ -147,7 +147,7 @@ function setupTable(props) {
|
|
|
147
147
|
borderProps,
|
|
148
148
|
cell: Cell,
|
|
149
149
|
skeleton: BORDER_SKELETONS[config.borderStyle].data,
|
|
150
|
-
trimWhitespace
|
|
150
|
+
trimWhitespace,
|
|
151
151
|
});
|
|
152
152
|
const footerComponent = row({
|
|
153
153
|
borderProps,
|
|
@@ -283,7 +283,7 @@ export function Skeleton(props) {
|
|
|
283
283
|
*
|
|
284
284
|
* Implementation inspired by https://github.com/vadimdemedes/ink/blob/master/test/helpers/create-stdout.ts
|
|
285
285
|
*/
|
|
286
|
-
const createStdout = () => {
|
|
286
|
+
const createStdout = ({ columns }) => {
|
|
287
287
|
// eslint-disable-next-line unicorn/prefer-event-target
|
|
288
288
|
const stdout = new EventEmitter();
|
|
289
289
|
// Override the rows so that ink doesn't clear the entire terminal when
|
|
@@ -292,7 +292,7 @@ const createStdout = () => {
|
|
|
292
292
|
// https://github.com/vadimdemedes/ink/blob/v5.0.1/src/ink.tsx#L174
|
|
293
293
|
// This might be a bad idea but it works.
|
|
294
294
|
stdout.rows = 10_000;
|
|
295
|
-
stdout.columns =
|
|
295
|
+
stdout.columns = columns;
|
|
296
296
|
const frames = [];
|
|
297
297
|
stdout.write = (data) => {
|
|
298
298
|
frames.push(data);
|
|
@@ -308,8 +308,8 @@ const createStdout = () => {
|
|
|
308
308
|
};
|
|
309
309
|
class Output {
|
|
310
310
|
stream;
|
|
311
|
-
constructor() {
|
|
312
|
-
this.stream = createStdout();
|
|
311
|
+
constructor(opts) {
|
|
312
|
+
this.stream = createStdout(opts);
|
|
313
313
|
}
|
|
314
314
|
printLastFrame() {
|
|
315
315
|
process.stdout.write(`${this.stream.lastFrame()}\n`);
|
|
@@ -404,7 +404,7 @@ export function printTable(options) {
|
|
|
404
404
|
renderPlainTable(options);
|
|
405
405
|
return;
|
|
406
406
|
}
|
|
407
|
-
const output = new Output();
|
|
407
|
+
const output = new Output({ columns: options.maxWidth === 'none' ? Infinity : getColumnWidth() });
|
|
408
408
|
const instance = render(React.createElement(Table, { ...options }), { stdout: output.stream });
|
|
409
409
|
instance.unmount();
|
|
410
410
|
output.printLastFrame();
|
|
@@ -417,7 +417,7 @@ export function printTable(options) {
|
|
|
417
417
|
* @returns {string} The rendered table as a string.
|
|
418
418
|
*/
|
|
419
419
|
export function makeTable(options) {
|
|
420
|
-
const output = new Output();
|
|
420
|
+
const output = new Output({ columns: options.maxWidth === 'none' ? Infinity : getColumnWidth() });
|
|
421
421
|
const instance = render(React.createElement(Table, { ...options }), { stdout: output.stream });
|
|
422
422
|
instance.unmount();
|
|
423
423
|
return output.stream.lastFrame() ?? '';
|
|
@@ -431,13 +431,17 @@ function Container(props) {
|
|
|
431
431
|
* @template T - An array of records where each record represents a table.
|
|
432
432
|
* @param {Object.<keyof T, TableOptions<T[keyof T]>>} tables - An object containing table options for each table.
|
|
433
433
|
* @param {Omit<ContainerProps, 'children'>} [options] - Optional container properties excluding 'children'.
|
|
434
|
-
* @throws {Error} Throws an error if the total number of rows across all tables exceeds
|
|
434
|
+
* @throws {Error} Throws an error if the total number of rows across all tables exceeds 10,000.
|
|
435
|
+
* @throws {Error} Throws an error if any of the tables have `maxWidth: "none"`.
|
|
435
436
|
*/
|
|
436
437
|
export function printTables(tables, options) {
|
|
437
438
|
if (tables.reduce((acc, table) => acc + table.data.length, 0) > 10_000) {
|
|
438
439
|
throw new Error('The data is too large to print multiple tables. Please use `printTable` instead.');
|
|
439
440
|
}
|
|
440
|
-
|
|
441
|
+
if (tables.some((table) => table.maxWidth === 'none')) {
|
|
442
|
+
throw new Error('printTables does not support `maxWidth: "none". Please use `printTable` instead.');
|
|
443
|
+
}
|
|
444
|
+
const output = new Output({ columns: getColumnWidth() });
|
|
441
445
|
const leftMargin = options?.marginLeft ?? options?.margin ?? 0;
|
|
442
446
|
const rightMargin = options?.marginRight ?? options?.margin ?? 0;
|
|
443
447
|
const columns = getColumnWidth() - (leftMargin + rightMargin);
|
package/lib/types.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ export type TableOptions<T extends Record<string, unknown>> = {
|
|
|
75
75
|
*/
|
|
76
76
|
padding?: number;
|
|
77
77
|
/**
|
|
78
|
-
* Maximum width of the table. Can be a number (e.g. 80) or a percentage (e.g. '80%').
|
|
78
|
+
* Maximum width of the table. Can be a number (e.g. 80) or a percentage (e.g. '80%'). Or set to 'none' for unlimited width.
|
|
79
79
|
*
|
|
80
80
|
* By default, the table will only take up as much space as it needs to fit the content. If it extends beyond the maximum width,
|
|
81
81
|
* it will wrap or truncate the content based on the `overflow` option. In other words, this property allows you to set the width
|
|
@@ -86,8 +86,14 @@ export type TableOptions<T extends Record<string, unknown>> = {
|
|
|
86
86
|
* If you provide a number or percentage that is larger than the terminal width, it will default to the terminal width.
|
|
87
87
|
*
|
|
88
88
|
* If you provide a number or percentage that is too small to fit the table, it will default to the minimum width of the table.
|
|
89
|
+
*
|
|
90
|
+
* If you provide 'none', the table will grow to its natural width, unbound by terminal width. This may render poorly in narrow terminals but
|
|
91
|
+
* it's useful because it will allow all the content to be visible without truncation or wrapping, which allows the user to resize their terminal
|
|
92
|
+
* to see all the content.
|
|
93
|
+
*
|
|
94
|
+
* @throws {Error} If you provide 'none' and you are using `printTables`.
|
|
89
95
|
*/
|
|
90
|
-
maxWidth?: Percentage | number;
|
|
96
|
+
maxWidth?: Percentage | number | 'none';
|
|
91
97
|
/**
|
|
92
98
|
* Exact width of the table. Can be a number (e.g. 80) or a percentage (e.g. '80%').
|
|
93
99
|
*
|
package/lib/utils.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export declare function getColumnWidth(): number;
|
|
|
34
34
|
* @param providedWidth - The width value provided.
|
|
35
35
|
* @returns The determined configured width.
|
|
36
36
|
*/
|
|
37
|
-
export declare function determineConfiguredWidth(providedWidth: number | Percentage | undefined, columns?: number): number;
|
|
37
|
+
export declare function determineConfiguredWidth(providedWidth: number | Percentage | 'none' | undefined, columns?: number): number;
|
|
38
38
|
export declare function getColumns<T extends Record<string, unknown>>(config: Config<T>, headings: Partial<T>): Column<T>[];
|
|
39
39
|
export declare function getHeadings<T extends Record<string, unknown>>(config: Config<T>): Partial<T>;
|
|
40
40
|
export declare function maybeStripAnsi<T extends Record<string, unknown>[]>(data: T, noStyle: boolean): T;
|
package/lib/utils.js
CHANGED
|
@@ -70,6 +70,8 @@ export function getColumnWidth() {
|
|
|
70
70
|
export function determineConfiguredWidth(providedWidth, columns = getColumnWidth()) {
|
|
71
71
|
if (!providedWidth)
|
|
72
72
|
return columns;
|
|
73
|
+
if (providedWidth === 'none')
|
|
74
|
+
return Infinity;
|
|
73
75
|
const num = typeof providedWidth === 'string' && providedWidth.endsWith('%')
|
|
74
76
|
? Math.floor((Number.parseInt(providedWidth, 10) / 100) * columns)
|
|
75
77
|
: typeof providedWidth === 'string'
|
|
@@ -120,6 +122,9 @@ export function getColumns(config, headings) {
|
|
|
120
122
|
// In that case, we don't want to reduce the column widths and just use the table's natural width.
|
|
121
123
|
if (maxWidth === 0)
|
|
122
124
|
return;
|
|
125
|
+
// The consumer has indicated they want an unbounded table
|
|
126
|
+
if (maxWidth === Infinity)
|
|
127
|
+
return;
|
|
123
128
|
// If the table is too wide, reduce the width of the largest column as little as possible to fit the table.
|
|
124
129
|
// If the table is still too wide, it will reduce the width of the next largest column and so on
|
|
125
130
|
while (tableWidth > maxWidth) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oclif/table",
|
|
3
3
|
"description": "Display table in terminal",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"bugs": "https://github.com/oclif/table/issues",
|
|
7
7
|
"dependencies": {
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@commitlint/config-conventional": "^19",
|
|
20
|
-
"@eslint/compat": "^1.
|
|
20
|
+
"@eslint/compat": "^1.4.0",
|
|
21
21
|
"@oclif/core": "^4",
|
|
22
22
|
"@oclif/prettier-config": "^0.2.1",
|
|
23
|
-
"@oclif/test": "^4.1.
|
|
23
|
+
"@oclif/test": "^4.1.14",
|
|
24
24
|
"@types/chai": "^4.3.16",
|
|
25
25
|
"@types/mocha": "^10.0.10",
|
|
26
26
|
"@types/node": "^18",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"ansis": "^3.17.0",
|
|
30
30
|
"chai": "^4.5.0",
|
|
31
31
|
"commitlint": "^19",
|
|
32
|
-
"eslint": "^9.
|
|
33
|
-
"eslint-config-oclif": "^6.0.
|
|
32
|
+
"eslint": "^9.38.0",
|
|
33
|
+
"eslint-config-oclif": "^6.0.110",
|
|
34
34
|
"eslint-config-prettier": "^10.1.8",
|
|
35
35
|
"eslint-config-xo": "^0.49.0",
|
|
36
36
|
"eslint-config-xo-react": "^0.28.0",
|
|
@@ -75,7 +75,9 @@
|
|
|
75
75
|
"posttest": "yarn lint",
|
|
76
76
|
"prepack": "yarn run build",
|
|
77
77
|
"prepare": "husky",
|
|
78
|
-
"test": "mocha --forbid-only \"test/**/*.test.+(ts|tsx)\" --parallel"
|
|
78
|
+
"test": "mocha --forbid-only \"test/**/*.test.+(ts|tsx)\" --parallel",
|
|
79
|
+
"test:examples": "mocha --forbid-only \"test/examples.snapshot.test.ts\"",
|
|
80
|
+
"test:examples:update": "UPDATE_SNAPSHOTS=1 mocha --forbid-only \"test/examples.snapshot.test.ts\""
|
|
79
81
|
},
|
|
80
82
|
"types": "lib/index.d.ts",
|
|
81
83
|
"type": "module"
|