clone

push a directory of html from the terminal and get a four-character url back. a deno cli on cloudflare

feat/source-stable-push
nzip / cli / main.ts
main.ts 6.2K
1#!/usr/bin/env -S deno run --allow-net --allow-read --allow-write --allow-env2/**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`, `status`, `app`, `vault`, `site`, and `notify`).6 *7 * Install and run it as a command rather than importing it:8 *9 * ```sh10 * deno install -g -A -f -n nzip jsr:@nzip/cli11 * nzip auth --server https://share.demo.dev12 * nzip site push ./site work:demo13 * ```14 *15 * @module16 */17// nzip — push HTML and get a tiny URL back.1819import { parseArgs } from "@std/cli/parse-args";20import { VERSION } from "@nzip/shared";21import { cmdAuth } from "./commands/auth.ts";22import { cmdApp } from "./commands/app.ts";23import { cmdNotify } from "./commands/notify.ts";24import { cmdSiteGroup } from "./commands/site.ts";25import { cmdStatus } from "./commands/sites.ts";26import { cmdVault } from "./commands/vault.ts";27import { requireConfig } from "./lib/config.ts";28import { fail, setJsonMode } from "./lib/fmt.ts";2930const HELP = `nzip — html share tool3132global:33 nzip --help show this command guide34 nzip --version [--json] show the installed CLI version3536commands:37 nzip38 ├─ auth [--server URL] [--token T] authenticate against the server39 ├─ status show server and vault status40 ├─ app41 │ ├─ init <alias|vault:alias> reserve a stable app URL42 │ └─ deploy build and deploy the configured lofi app43 ├─ vault44 │ ├─ add <name> [--slot N] [--default-ttl 14d|forever|inherit]45 │ ├─ update <name> [--default-ttl 14d|forever|inherit]46 │ ├─ ls list vaults47 │ └─ default <temporary|permanent> <name>48 ├─ site49 │ ├─ push <dir|file> [target] [--new] publish content; reuse source by default50 │ ├─ cp <target> [dir] [--overwrite] copy a hosted bundle51 │ ├─ show <target> show site details52 │ ├─ policy <target> [--ttl ...] [--password PW | --no-password]53 │ ├─ ls [vault] list sites54 │ ├─ where <target> print this machine's source directory55 │ ├─ rm <target> [--yes] delete a site56 │ └─ revert <target> [--to N] [--list] inspect or restore push history57 └─ notify58 ├─ send <body> [--title TEXT] [--open TARGET] [--tag TEXT]59 ├─ test queue a diagnostic notification60 ├─ pair allow device pairing for 10 minutes61 ├─ approve <code> --name NAME [--yes]62 ├─ devices [--all] list current notification devices63 └─ revoke <device-id> [--yes] revoke a notification device6465targets: 2a3f | work:demo | demo (alias in temporary default vault)6667agent mode: add --json to any command for one-line JSON on stdout;68errors go to stderr as {"ok":false,"error":…,"hint":…} with a suggested next step.6970vault guard: set "allowVaults": ["home"] in config.json to restrict this install71to named vaults — raw addresses are authenticated and mapped to a vault before use.7273notification privacy: titles and bodies may appear on a lock screen; never include74passwords, tokens, private URLs, or sensitive personal data.75`;7677/**78 * Runs the nzip command-line interface with the supplied arguments.79 *80 * @param argv Command-line arguments without the executable name. Defaults to81 * the current process arguments.82 * @throws If configuration, validation, or a command handler fails.83 */84export async function main(argv = Deno.args): Promise<void> {85 const args = parseArgs(argv, {86 string: [87 "ttl",88 "to",89 "slot",90 "server",91 "token",92 "password",93 "name",94 "description",95 "default-ttl",96 "default-for",97 "framework",98 "output",99 "build-task",100 "title",101 "open",102 "tag",103 ],104 boolean: [105 "yes",106 "list",107 "help",108 "version",109 "no-password",110 "overwrite",111 "json",112 "no-description",113 "all",114 "no-default-for",115 "new",116 ],117 alias: { h: "help", V: "version", y: "yes" },118 });119 setJsonMode(args.json);120 const [command, ...rest] = args._.map(String);121122 if (args.version) {123 console.log(args.json ? JSON.stringify({ version: VERSION }) : `nzip ${VERSION}`);124 return;125 }126127 if (args.help || !command) {128 console.log(HELP);129 return;130 }131132 if (command === "auth") return await cmdAuth(args.server, args.token);133134 if (!["app", "site", "status", "notify", "vault"].includes(command)) {135 fail(`unknown command: ${command}\n\n${HELP}`);136 }137138 const config = await requireConfig();139 const slot = args.slot === undefined ? undefined : parseInt(args.slot, 10);140 const toSeq = args.to === undefined ? undefined : parseInt(args.to, 10);141142 switch (command) {143 case "site":144 return await cmdSiteGroup(config, rest, {145 ttl: args.ttl,146 password: args.password,147 noPassword: args["no-password"],148 newSite: args.new,149 overwrite: args.overwrite,150 yes: args.yes,151 toSeq,152 list: args.list,153 });154 case "app":155 return await cmdApp(config, rest, {156 framework: args.framework,157 output: args.output,158 buildTask: args["build-task"],159 });160 case "status":161 return await cmdStatus(config);162 case "notify":163 return await cmdNotify(config, rest, {164 title: args.title,165 open: args.open,166 tag: args.tag,167 name: args.name,168 yes: args.yes,169 all: args.all,170 });171 case "vault":172 return await cmdVault(config, rest, {173 slot,174 newName: args.name,175 description: args.description,176 clearDescription: args["no-description"],177 defaultTtl: args["default-ttl"],178 defaultFor: args["default-for"],179 clearDefaultFor: args["no-default-for"],180 });181 default:182 fail(`unknown command: ${command}\n\n${HELP}`);183 }184}185186if (import.meta.main) {187 main().catch((e) => fail((e as Error).message));188}