diff --git a/src/cli.js b/src/cli.js index f134708..96c0706 100755 --- a/src/cli.js +++ b/src/cli.js @@ -19,18 +19,19 @@ function usage() { return `Usage: sk-az-tools [options] Commands: - list-apps [--display-name ] - list-app-permissions --app-id [--resolve] - list-app-grants --app-id - table [--pretty] + list-apps [--display-name|-n ] + list-app-permissions --app-id|-i [--resolve|-r] + list-app-grants --app-id|-i + table [--pretty|-p] [--quote-guids|-g] Options: - --display-name Filter apps by exact display name - --app-id Application (client) ID - --resolve Resolve permission GUIDs to human-readable values - --query Filter output JSON using JMESPath - --pretty Use normalized column widths for Markdown table output - --output Output format: json|table|prettytable (default: json) + -n, --display-name Filter apps by exact display name + -i, --app-id Application (client) ID + -r, --resolve Resolve permission GUIDs to human-readable values + -q, --query 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 + -o, --output Output format: json|table|prettytable (default: json) -h, --help Show this help message`; } @@ -77,12 +78,13 @@ async function main() { args: argv.slice(1), options: { help: { type: "boolean", short: "h" }, - "display-name": { type: "string" }, - "app-id": { type: "string" }, - resolve: { type: "boolean" }, - query: { type: "string" }, - pretty: { type: "boolean" }, - output: { type: "string" }, + "display-name": { type: "string", short: "n" }, + "app-id": { type: "string", short: "i" }, + resolve: { type: "boolean", short: "r" }, + query: { type: "string", short: "q" }, + pretty: { type: "boolean", short: "p" }, + "quote-guids": { type: "boolean", short: "g" }, + output: { type: "string", short: "o" }, }, strict: true, allowPositionals: false, @@ -148,9 +150,9 @@ async function main() { const filtered = outputFiltered(result, values.query); if (command === "table") { - console.log(toMarkdownTable(filtered, Boolean(values.pretty))); + console.log(toMarkdownTable(filtered, Boolean(values.pretty), Boolean(values["quote-guids"]))); } else if (outputFormat === "prettytable") { - console.log(toMarkdownTable(filtered, true)); + console.log(toMarkdownTable(filtered, true, Boolean(values["quote-guids"]))); } else if (outputFormat === "table") { console.log(toMarkdownTable(filtered)); } else { diff --git a/src/markdown.js b/src/markdown.js index c44afb5..8b7a634 100644 --- a/src/markdown.js +++ b/src/markdown.js @@ -7,6 +7,11 @@ function formatCell(value) { return text.replaceAll("|", "\\|").replaceAll("\n", "
"); } +function isGuid(value) { + return typeof value === "string" + && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value); +} + function getScalarRowsAndHeaders(value) { let rows; if (Array.isArray(value)) { @@ -46,8 +51,13 @@ function getScalarRowsAndHeaders(value) { return { headers, rows }; } -export function toMarkdownTable(value, pretty = false) { +export function toMarkdownTable(value, pretty = false, quoteGuids = false) { const { headers, rows } = getScalarRowsAndHeaders(value); + const renderCell = (raw) => { + const text = formatCell(raw); + return quoteGuids && isGuid(raw) ? `\`${text}\`` : text; + }; + if (!pretty) { const headerLine = `| ${headers.join(" | ")} |`; const separatorLine = `| ${headers.map(() => "---").join(" | ")} |`; @@ -60,7 +70,7 @@ export function toMarkdownTable(value, pretty = false) { const widths = headers.map((header, idx) => Math.max( header.length, - ...rows.map((row) => formatCell(row[headers[idx]]).length), + ...rows.map((row) => renderCell(row[headers[idx]]).length), ) ); @@ -70,7 +80,7 @@ export function toMarkdownTable(value, pretty = false) { const headerLine = renderRow(headers); const separatorLine = `|-${widths.map((w) => "-".repeat(w)).join("-|-")}-|`; const rowLines = rows.map((row) => - renderRow(headers.map((header) => formatCell(row[header]))) + renderRow(headers.map((header) => renderCell(row[header]))) ); return [headerLine, separatorLine, ...rowLines].join("\n");