flagstaff
Guides

Tables

Draw a table as a string with table(), or hoist tableComponent() so a pipe gets header-and-value pairs and --json gets the rows.

flagstaff/table has table(), which returns the grid as a string, and tableComponent(), which hoists on the loop.

table(rows, options)

grid.mjs
import { table } from 'flagstaff/table';

console.log(table([['ora', '99'], ['log-update', '99']], { head: ['host', 'tests'], align: ['left', 'right'], width: 30 }));
console.log(table([['古池や', 'Bashō'], ['a very long cell that wraps', 'x']], { head: ['poem', 'poet'], width: 26 }));
node grid.mjs
┌────────────┬───────┐
│ host       │ tests │
├────────────┼───────┤
│ ora        │    99 │
│ log-update │    99 │
└────────────┴───────┘
┌────────────────┬───────┐
│ poem           │ poet  │
├────────────────┼───────┤
│ 古池や         │ Bashō │
│ a very long    │ x     │
│ cell that      │       │
│ wraps          │       │
└────────────────┴───────┘
optiondefault
head—column headers; without them there is no header row
width80the most columns the whole table may take
alignleft'left' or 'right' per column
terminalthe real processthe terminal a linked cell is rendered for

A row is an array of cells, and a cell is a string or { text, href } — a link, rendered the way box links are. Every row is measured in terminal columns, so a wide character never pushes the grid out, and a cell too wide for its column wraps inside it rather than widening the table. The table never overruns the width it was given (builtins.test.ts checks 20, 40 and 80 columns with a wide cell).

tableComponent(): rows a reader can use

A grid in a log file is box-drawing characters around the data. Hoisted as a component, a table is drawn only on a terminal. Everywhere else each row is one line of header: value pairs:

results.mjs
import { hoist } from 'flagstaff/loop';
import { tableComponent } from 'flagstaff/table';

import { json, rt } from './rt.mjs';

const rows = [
  ['api', 'passed', '112'],
  ['web', 'failed', '3'],
];
hoist(tableComponent({ head: ['suite', 'result', 'tests'] }), rt, { rows }, { json }).lower();
node results.mjs
suite: api, result: passed, tests: 112
suite: web, result: failed, tests: 3

Without head, the pairs fall back to tab-separated values. Under --json the rows are the state, so an agent gets them as data:

node results.mjs --json
{"event":"table","state":{"rows":[["api","passed","112"],["web","failed","3"]]}}
{"event":"table","state":{"rows":[["api","passed","112"],["web","failed","3"]]}}

Two events, because hoisting is one transition and lowering is another.

Coming from cli-table3

flagstaff/cli-table3 is cli-table3 0.6.5's API — head, chars, style, colWidths, rowHeights, alignment, wordWrap, colSpan and rowSpan, href — graded by the cases of cli-table3's own suite that go through its public API. It extends Array, as cli-table3 does. See Coming from cli-table3 and Compatibility for what that grade covers.

On this page