#!/usr/bin/env node // SPDX-License-Identifier: MIT import { parseArgs } from "node:util"; import { runCommand } from "./cli/commands.js"; import { normalizeOutputFormat, omitPermissionGuidColumns, outputFiltered, parseHeaderSpec, renderOutput, } from "./cli/utils.js"; function usage() { return `Usage: sk-az-tools [options] Commands: login Authenticate selected resources logout Sign out and clear login state list-apps List Entra applications list-app-permissions List required permissions for an app list-app-grants List OAuth2 grants for an app list-resource-permissions List available permissions for a resource app table Render stdin JSON as Markdown table Global options (all commands): -q, --query -o, --output table|t|alignedtable|at|prettytable|pt|tsv -h, --help Use: sk-az-tools --help or: sk-az-tools --help`; } function usageListApps() { return `Usage: sk-az-tools list-apps [--display-name|-n ] [--app-id|-i ] [--filter|-f ] [global options] Options: -n, --display-name Get app by name -i, --app-id Get app by id -f, --filter Filter by app display name glob`; } function usageLogin() { return `Usage: sk-az-tools login [--resources ] [--use-device-code] [--no-browser] [--browser ] [--browser-profile ] [global options] Options: --resources Comma-separated resources: graph,devops,arm (default: all) --use-device-code Use device code flow instead of interactive flow --no-browser Do not launch browser; print interactive URL to stderr --browser Browser keyword: brave|browser|browserPrivate|chrome|edge|firefox --browser-profile Chromium profile name (e.g. Default, "Profile 1")`; } function usageLogout() { return `Usage: sk-az-tools logout [--all] [global options] Options: --all Clear login state and remove all cached accounts`; } function usageListAppPermissions() { return `Usage: sk-az-tools list-app-permissions --app-id|-i [--resolve|-r] [--short|-s] [--filter|-f ] [global options] Options: -i, --app-id Application (client) ID (required) -r, --resolve Resolve permission GUIDs to human-readable values -s, --short Makes output more compact -f, --filter Filter by permission name glob`; } function usageListAppGrants() { return `Usage: sk-az-tools list-app-grants --app-id|-i [global options] Options: -i, --app-id Application (client) ID (required)`; } function usageListResourcePermissions() { return `Usage: sk-az-tools list-resource-permissions [--app-id|-i | --display-name|-n ] [--filter|-f ] [global options] Options: -i, --app-id Resource app ID -n, --display-name Resource app display name -f, --filter Filter by permission name glob`; } function usageTable() { return `Usage: sk-az-tools table [--header|-H ] [global options] Options: -H, --header Header mode/spec: auto|a (default), original|o, OR "col1, col2" OR "key1: Label 1, key2: Label 2"`; } function usageCommand(command) { switch (command) { case "login": return usageLogin(); case "list-apps": return usageListApps(); case "logout": return usageLogout(); case "list-app-permissions": return usageListAppPermissions(); case "list-app-grants": return usageListAppGrants(); case "list-resource-permissions": return usageListResourcePermissions(); case "table": return usageTable(); default: return `Unknown command: ${command}\n\n${usage()}`; } } async function main() { const argv = process.argv.slice(2); const command = argv[0]; if (!command) { console.log(usage()); process.exit(0); } if (command === "-h" || command === "--help") { const helpCommand = argv[1]; console.log(helpCommand ? usageCommand(helpCommand) : usage()); process.exit(0); } const { values } = parseArgs({ args: argv.slice(1), options: { help: { type: "boolean", short: "h" }, "display-name": { type: "string", short: "n" }, "app-id": { type: "string", short: "i" }, resources: { type: "string" }, "use-device-code": { type: "boolean" }, "no-browser": { type: "boolean" }, browser: { type: "string" }, "browser-profile": { type: "string" }, all: { type: "boolean" }, resolve: { type: "boolean", short: "r" }, short: { type: "boolean", short: "s" }, filter: { type: "string", short: "f" }, query: { type: "string", short: "q" }, header: { type: "string", short: "H" }, output: { type: "string", short: "o" }, }, strict: true, allowPositionals: false, }); if (values.help) { console.log(usageCommand(command)); process.exit(0); } const outputFormat = normalizeOutputFormat(values.output); const result = await runCommand(command, values); const filtered = outputFiltered(result, values.query); const output = command === "list-app-permissions" && values.short ? omitPermissionGuidColumns(filtered) : filtered; const headerSpec = parseHeaderSpec(values.header); renderOutput(command, output, outputFormat, headerSpec); } main().catch((err) => { console.error(`Error: ${err.message}`); console.error(usage()); process.exit(1); });