feat(table): add header spec support and explicit auto mode
This commit is contained in:
55
src/cli.js
55
src/cli.js
@@ -22,7 +22,7 @@ Commands:
|
||||
list-apps [--display-name|-n <name>]
|
||||
list-app-permissions --app-id|-i <appId> [--resolve|-r] [--short|-s]
|
||||
list-app-grants --app-id|-i <appId>
|
||||
table [--pretty|-p] [--quote-guids|-g]
|
||||
table [--pretty|-p] [--quote-guids|-g] [--header|-H <spec|auto|a>]
|
||||
|
||||
Options:
|
||||
-n, --display-name <name> Filter apps by exact display name
|
||||
@@ -32,6 +32,7 @@ Options:
|
||||
-q, --query <jmespath> Filter output JSON using JMESPath
|
||||
-p, --pretty Use normalized column widths for Markdown table output
|
||||
-g, --quote-guids In pretty tables, wrap GUID values in backticks
|
||||
-H, --header <value> Header mode/spec: auto|a OR "col1, col2" OR "key1: Label 1, key2: Label 2"
|
||||
-o, --output <format> Output format: json|table|prettytable (default: json)
|
||||
-h, --help Show this help message`;
|
||||
}
|
||||
@@ -42,6 +43,40 @@ function outputFiltered(object, query) {
|
||||
: object;
|
||||
}
|
||||
|
||||
function parseHeaderSpec(headerValue) {
|
||||
if (!headerValue) {
|
||||
return { mode: "default" };
|
||||
}
|
||||
|
||||
const raw = headerValue.trim();
|
||||
if (raw === "" || raw.toLowerCase() === "auto" || raw.toLowerCase() === "a") {
|
||||
return { mode: "auto" };
|
||||
}
|
||||
|
||||
const parts = raw.split(",").map((p) => p.trim()).filter(Boolean);
|
||||
const isMap = parts.some((p) => p.includes(":"));
|
||||
|
||||
if (!isMap) {
|
||||
return { mode: "list", labels: parts };
|
||||
}
|
||||
|
||||
const map = {};
|
||||
for (const part of parts) {
|
||||
const idx = part.indexOf(":");
|
||||
if (idx < 0) {
|
||||
throw new Error(`Invalid --header mapping segment: '${part}'`);
|
||||
}
|
||||
const key = part.slice(0, idx).trim();
|
||||
const label = part.slice(idx + 1).trim();
|
||||
if (!key || !label) {
|
||||
throw new Error(`Invalid --header mapping segment: '${part}'`);
|
||||
}
|
||||
map[key] = label;
|
||||
}
|
||||
|
||||
return { mode: "map", map };
|
||||
}
|
||||
|
||||
function omitPermissionGuidColumns(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => omitPermissionGuidColumns(item));
|
||||
@@ -97,6 +132,7 @@ async function main() {
|
||||
query: { type: "string", short: "q" },
|
||||
pretty: { type: "boolean", short: "p" },
|
||||
"quote-guids": { type: "boolean", short: "g" },
|
||||
header: { type: "string", short: "H" },
|
||||
output: { type: "string", short: "o" },
|
||||
},
|
||||
strict: true,
|
||||
@@ -165,12 +201,23 @@ async function main() {
|
||||
const output = command === "list-app-permissions" && values.short
|
||||
? omitPermissionGuidColumns(filtered)
|
||||
: filtered;
|
||||
const headerSpec = parseHeaderSpec(values.header);
|
||||
if (command === "table") {
|
||||
console.log(toMarkdownTable(output, Boolean(values.pretty), Boolean(values["quote-guids"])));
|
||||
console.log(toMarkdownTable(
|
||||
output,
|
||||
Boolean(values.pretty),
|
||||
Boolean(values["quote-guids"]),
|
||||
headerSpec,
|
||||
));
|
||||
} else if (outputFormat === "prettytable") {
|
||||
console.log(toMarkdownTable(output, true, Boolean(values["quote-guids"])));
|
||||
console.log(toMarkdownTable(
|
||||
output,
|
||||
true,
|
||||
Boolean(values["quote-guids"]),
|
||||
headerSpec,
|
||||
));
|
||||
} else if (outputFormat === "table") {
|
||||
console.log(toMarkdownTable(output));
|
||||
console.log(toMarkdownTable(output, false, false, headerSpec));
|
||||
} else {
|
||||
console.log(JSON.stringify(output, null, 2));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user