Fixed incorrect handling of table output.
All checks were successful
build / build (push) Successful in 10s
All checks were successful
build / build (push) Successful in 10s
This commit is contained in:
@@ -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",
|
||||||
|
|||||||
@@ -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) => {
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
Reference in New Issue
Block a user