Fixed incorrect handling of table output.
All checks were successful
build / build (push) Successful in 10s

This commit is contained in:
2026-03-06 23:03:01 +01:00
parent 36dc8df4b7
commit 9a6ff66d72
4 changed files with 25 additions and 25 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "@slawek/sk-tools", "name": "@slawek/sk-tools",
"version": "0.1.0", "version": "0.1.1",
"type": "module", "type": "module",
"files": [ "files": [
"dist", "dist",

View File

@@ -113,7 +113,7 @@ async function main(): Promise<void> {
const filtered = outputFiltered(result, typedValues.query); const filtered = outputFiltered(result, typedValues.query);
const headerSpec = parseHeaderSpec(typedValues.header); const headerSpec = parseHeaderSpec(typedValues.header);
renderOutput(command, filtered, outputFormat, headerSpec); renderOutput(outputFormat, headerSpec, filtered);
} }
main().catch((err: unknown) => { main().catch((err: unknown) => {

View File

@@ -201,28 +201,25 @@ export async function readCsvFromStdin(separator: string): Promise<unknown> {
} }
export function renderOutput( export function renderOutput(
command: string,
output: unknown,
outputFormat: OutputFormat, outputFormat: OutputFormat,
headerSpec: HeaderSpec, headerSpec: HeaderSpec,
output: unknown,
): void { ): void {
if (outputFormat === "tsv") { if (outputFormat === "tsv") {
console.log(toTsv(output)); console.log(toTsv(output));
return; return;
} }
if (command === "table") { // Map output format to a markdown table mode.
console.log(toMarkdownTable( // - table: compact
output, // - alignedtable: aligned columns, no quoting
outputFormat === "alignedtable" || outputFormat === "prettytable", // - prettytable: aligned columns + quoting selected values
headerSpec, if (outputFormat === "prettytable") {
)); console.log(toMarkdownTable(output, "prettytable", headerSpec));
} else if (outputFormat === "alignedtable") { } else if (outputFormat === "alignedtable") {
console.log(toMarkdownTable(output, true, headerSpec)); console.log(toMarkdownTable(output, "alignedtable", headerSpec));
} else if (outputFormat === "prettytable") {
console.log(toMarkdownTable(output, true, headerSpec));
} else if (outputFormat === "table") { } else if (outputFormat === "table") {
console.log(toMarkdownTable(output, false, headerSpec)); console.log(toMarkdownTable(output, "table", headerSpec));
} else { } else {
console.log(JSON.stringify(output, null, 2)); console.log(JSON.stringify(output, null, 2));
} }

View File

@@ -10,6 +10,8 @@ type HeaderSpec =
| { mode: "list"; labels: string[] } | { mode: "list"; labels: string[] }
| { mode: "map"; map: Record<string, string> }; | { mode: "map"; map: Record<string, string> };
type TableMode = "table" | "alignedtable" | "prettytable";
function formatCell(value: unknown): string { function formatCell(value: unknown): string {
const text = value == null const text = value == null
? "" ? ""
@@ -24,15 +26,15 @@ const inlineCodePredicates = [
&& /^(?:\d{1,3}\.){3}\d{1,3}(?:\/(?:\d{1,2}|(?:\d{1,3}\.){3}\d{1,3}))?$/.test(value), && /^(?:\d{1,3}\.){3}\d{1,3}(?:\/(?:\d{1,2}|(?:\d{1,3}\.){3}\d{1,3}))?$/.test(value),
]; ];
function renderCell(raw: Scalar): string { function renderCell(raw: Scalar, shouldQuote: boolean): string {
const text = formatCell(raw); const text = formatCell(raw);
if (shouldQuote) {
for (const predicate of inlineCodePredicates) { for (const predicate of inlineCodePredicates) {
if (predicate(raw)) { if (predicate(raw)) {
return `\`${text}\``; return `\`${text}\``;
} }
} }
}
return text; return text;
} }
@@ -106,9 +108,10 @@ function getScalarRowsAndHeaders(value: unknown): { headers: string[]; rows: Sca
export function toMarkdownTable( export function toMarkdownTable(
value: unknown, value: unknown,
pretty = false, mode: TableMode = "table",
headerSpec: HeaderSpec = { mode: "default" }, headerSpec: HeaderSpec = { mode: "default" },
): string { ): string {
const prettyMode = mode === "prettytable";
const { headers, rows } = getScalarRowsAndHeaders(value); const { headers, rows } = getScalarRowsAndHeaders(value);
const headerDefinitions = headers.map((key, idx) => { const headerDefinitions = headers.map((key, idx) => {
let label = key; let label = key;
@@ -122,11 +125,11 @@ export function toMarkdownTable(
return { key, label }; return { key, label };
}); });
if (!pretty) { if (mode !== "alignedtable" && mode !== "prettytable") {
const headerLine = `| ${headerDefinitions.map((h) => h.label).join(" | ")} |`; const headerLine = `| ${headerDefinitions.map((h) => h.label).join(" | ")} |`;
const separatorLine = `| ${headerDefinitions.map(() => "---").join(" | ")} |`; const separatorLine = `| ${headerDefinitions.map(() => "---").join(" | ")} |`;
const rowLines = rows.map((row) => const rowLines = rows.map((row) =>
`| ${headerDefinitions.map((h) => formatCell(row[h.key])).join(" | ")} |`, `| ${headerDefinitions.map((h) => renderCell(row[h.key], prettyMode)).join(" | ")} |`,
); );
return [headerLine, separatorLine, ...rowLines].join("\n"); return [headerLine, separatorLine, ...rowLines].join("\n");
} }
@@ -134,7 +137,7 @@ export function toMarkdownTable(
const widths = headerDefinitions.map((header, idx) => const widths = headerDefinitions.map((header, idx) =>
Math.max( Math.max(
header.label.length, header.label.length,
...rows.map((row) => renderCell(row[headerDefinitions[idx].key]).length), ...rows.map((row) => renderCell(row[headerDefinitions[idx].key], prettyMode).length),
) )
); );
@@ -144,7 +147,7 @@ export function toMarkdownTable(
const headerLine = renderRow(headerDefinitions.map((h) => h.label)); const headerLine = renderRow(headerDefinitions.map((h) => h.label));
const separatorLine = `|-${widths.map((w) => "-".repeat(w)).join("-|-")}-|`; const separatorLine = `|-${widths.map((w) => "-".repeat(w)).join("-|-")}-|`;
const rowLines = rows.map((row) => const rowLines = rows.map((row) =>
renderRow(headerDefinitions.map((header) => renderCell(row[header.key]))), renderRow(headerDefinitions.map((header) => renderCell(row[header.key], prettyMode))),
); );
return [headerLine, separatorLine, ...rowLines].join("\n"); return [headerLine, separatorLine, ...rowLines].join("\n");