Add support for CSV and TSV input formats in table command
All checks were successful
build / build (push) Successful in 12s

This commit is contained in:
2026-03-06 11:43:47 +01:00
parent 21b6a51330
commit 8cbd1d6399
7 changed files with 133 additions and 9 deletions

View File

@@ -24,6 +24,7 @@ import {
type CliValues = {
help?: boolean;
type?: string;
from?: string;
method?: string;
url?: string;
"display-name"?: string;
@@ -109,6 +110,7 @@ async function main(): Promise<void> {
options: {
help: { type: "boolean", short: "h" },
type: { type: "string", short: "t" },
from: { type: "string", short: "F" },
method: { type: "string" },
url: { type: "string" },
"display-name": { type: "string", short: "n" },

View File

@@ -19,7 +19,7 @@ export async function runCommand(command: string, values: CommandValues): Promis
case "logout":
return runLogoutCommand(values);
case "table":
return runTableCommand();
return runTableCommand(values);
case "list-apps":
return runListAppsCommand(values);
case "list-app-permissions":

View File

@@ -1,14 +1,28 @@
// SPDX-License-Identifier: MIT
import { readJsonFromStdin } from "../utils.ts";
import { readCsvFromStdin, readJsonFromStdin } from "../utils.ts";
import type { CommandValues } from "./types.ts";
export function usageTable(): string {
return `Usage: sk-az-tools table [--header|-H <definition|auto|a|original|o>] [global options]
return `Usage: sk-az-tools table [--from|-F <json|csv|tsv>] [--header|-H <definition|auto|a|original|o>] [global options]
Options:
-H, --header <value> Header mode: auto|a (default), original|o, or "col1, col2" or "key1: Label 1, key2: Label 2"`;
--from, -F <json|csv|tsv> Input format on stdin (default: json)
--header, -H <value> Header mode: auto|a (default), original|o, or "col1, col2" or "key1: Label 1, key2: Label 2"`;
}
export async function runTableCommand(): Promise<unknown> {
return readJsonFromStdin();
export async function runTableCommand(values: CommandValues): Promise<unknown> {
const from = (values.from ?? "json").toString().trim().toLowerCase();
if (from === "json") {
return readJsonFromStdin();
}
if (from === "csv") {
return readCsvFromStdin(",");
}
if (from === "tsv") {
return readCsvFromStdin("\t");
}
throw new Error(`Invalid --from '${values.from}'. Allowed: json, csv, tsv`);
}

View File

@@ -3,6 +3,7 @@
export type CommandValues = {
[key: string]: string | boolean | undefined;
type?: string;
from?: string;
method?: string;
url?: string;
header?: string;

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
import jmespath from "jmespath";
import { dsvFormat } from "d3-dsv";
import { toMarkdownTable } from "../markdown.ts";
@@ -175,6 +176,43 @@ export async function readJsonFromStdin(): Promise<unknown> {
}
}
export async function readCsvFromStdin(separator: string): Promise<unknown> {
if (!separator) {
throw new Error("separator is required");
}
if (separator.length !== 1) {
throw new Error("separator must be a single character");
}
const input = await new Promise<string>((resolve, reject) => {
let data = "";
process.stdin.setEncoding("utf8");
process.stdin.on("data", (chunk: string) => {
data += chunk;
});
process.stdin.on("end", () => {
resolve(data);
});
process.stdin.on("error", (err) => {
reject(err);
});
});
if (!input.trim()) {
throw new Error("No separated values input provided on stdin");
}
try {
const parser = dsvFormat(separator);
const rows = parser.parse(input);
if (rows.columns.some((header: string) => header.trim() === "")) {
throw new Error("header row contains empty column name");
}
return rows;
} catch (err) {
throw new Error(`Invalid separated input on stdin: ${(err as Error).message}`);
}
}
export function renderOutput(
command: string,
output: unknown,