12/**3 * `nzip` — push a directory of HTML from the terminal and get a four-character4 * URL back. This is the CLI entrypoint; it parses argv and dispatches to the5 * command handlers (`auth`, `vault`, `push`, `share`, `ls`, `where`, `rm`,6 * `status`, `revert`).7 *8 * Install and run it as a command rather than importing it:9 *10 * ```sh11 * deno install -g -A -f -n nzip jsr:@nzip/cli12 * nzip auth --server https://share.example.com13 * nzip push ./site work:demo14 * ```15 *16 * @module17 */18// nzip — push HTML and get a tiny URL back.1920import { parseArgs } from "@std/cli/parse-args";21import { cmdAuth } from "./commands/auth.ts";22import { cmdPush } from "./commands/push.ts";23import { cmdLs, cmdRevert, cmdRm, cmdShare, cmdStatus } from "./commands/sites.ts";24import { cmdVault } from "./commands/vault.ts";25import { cmdWhere } from "./commands/where.ts";26import { requireConfig } from "./lib/config.ts";27import { fail, setJsonMode } from "./lib/fmt.ts";2829const HELP = `nzip — html share tool3031usage:32 nzip auth [--server URL] [--token T] authenticate against the server33 nzip vault add <name> [--slot N] register a vault (16 slots, 0x0-0xf)34 nzip vault ls list vaults35 nzip vault default <name> set default vault36 nzip push <dir|file> [target] [--ttl 14d|30d|forever]37 nzip share <target> [--ttl ...] [--password PW | --no-password]38 resolve + print url; set ttl/password39 nzip ls [vault] list sites40 nzip where <target> print the local dir this machine pushed from41 nzip rm <target> [--yes] delete a site42 nzip status server + vault overview43 nzip revert <target> [--to N] [--list] repoint to a previous push4445targets: 2a3f | work:demo | demo (alias in default vault)4647agent mode: add --json to any command for one-line JSON on stdout;48errors go to stderr as {"ok":false,"error":…,"hint":…} with a suggested next step.4950vault guard: set "allowVaults": ["home"] in config.json to restrict this install51to named vaults — pushes/aliases outside the list are refused (agent guardrail).52`;5354async function main(): Promise<void> {55 const args = parseArgs(Deno.args, {56 string: ["ttl", "to", "slot", "server", "token", "password"],57 boolean: ["yes", "list", "help", "no-password", "json"],58 alias: { h: "help", y: "yes" },59 });60 setJsonMode(args.json);61 const [command, ...rest] = args._.map(String);6263 if (args.help || !command) {64 console.log(HELP);65 return;66 }6768 if (command === "auth") return await cmdAuth(args.server, args.token);6970 const config = await requireConfig();71 const slot = args.slot === undefined ? undefined : parseInt(args.slot, 10);72 const toSeq = args.to === undefined ? undefined : parseInt(args.to, 10);7374 switch (command) {75 case "push":76 return await cmdPush(config, rest[0], rest[1], args.ttl);77 case "share":78 return await cmdShare(config, rest[0], args.ttl, args.password, args["no-password"]);79 case "ls":80 return await cmdLs(config, rest[0]);81 case "where":82 return await cmdWhere(config, rest[0]);83 case "rm":84 return await cmdRm(config, rest[0], args.yes);85 case "status":86 return await cmdStatus(config);87 case "revert":88 return await cmdRevert(config, rest[0], toSeq, args.list);89 case "vault":90 return await cmdVault(config, rest[0], rest[1], slot);91 default:92 fail(`unknown command: ${command}\n\n${HELP}`);93 }94}9596if (import.meta.main) {97 main().catch((e) => fail((e as Error).message));98}