anonli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types/config.ts","../src/lib/config.ts","../src/lib/errors.ts","../package.json","../src/lib/constants.ts","../src/lib/api.ts","../src/index.ts","../src/commands/login.ts","../src/lib/auth.ts","../src/lib/ui.ts","../src/lib/theme.ts","../src/lib/brand.ts","../src/commands/logout.ts","../src/commands/whoami.ts","../src/commands/drop.ts","../src/commands/drop-upload.ts","../src/lib/limits.ts","../src/lib/crypto.ts","../src/commands/drop-list.ts","../src/commands/drop-delete.ts","../src/lib/drop-url.ts","../src/commands/drop-download.ts","../src/commands/drop-toggle.ts","../src/commands/drop-info.ts","../src/commands/drop-share.ts","../src/commands/alias.ts","../src/commands/alias-new.ts","../src/commands/alias-list.ts","../src/commands/alias-delete.ts","../src/commands/alias-toggle.ts","../src/commands/alias-update.ts","../src/commands/alias-stats.ts","../src/commands/recipient.ts","../src/commands/domain.ts","../src/commands/apikey.ts","../src/commands/config-cmd.ts","../src/commands/update.ts","../src/commands/subscribe.ts","../src/commands/completions.ts","../src/lib/version-check.ts"],"sourcesContent":["export interface AnonliConfig {\n apiKey?: string;\n baseUrl: string;\n lastVersionCheck?: number;\n latestVersion?: string;\n userEmail?: string;\n userName?: string | null;\n}\n\nexport const DEFAULT_CONFIG: AnonliConfig = {\n baseUrl: \"https://anon.li\",\n};\n","import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport type { AnonliConfig } from \"../types/config.js\";\nimport { DEFAULT_CONFIG } from \"../types/config.js\";\n\nfunction getConfigPath(): string {\n const xdg = process.env.XDG_CONFIG_HOME;\n const base = xdg || path.join(os.homedir(), \".config\");\n return path.join(base, \"anonli.json\");\n}\n\nexport function loadConfig(): AnonliConfig {\n const configPath = getConfigPath();\n try {\n const raw = fs.readFileSync(configPath, \"utf-8\");\n const parsed = JSON.parse(raw);\n const config = { ...DEFAULT_CONFIG, ...parsed };\n if (!config.baseUrl) {\n config.baseUrl = DEFAULT_CONFIG.baseUrl;\n }\n return config;\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport function saveConfig(config: AnonliConfig): void {\n const configPath = getConfigPath();\n const dir = path.dirname(configPath);\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + \"\\n\", {\n mode: 0o600,\n });\n}\n\nexport function getApiKey(): string | undefined {\n return process.env.ANONLI_API_KEY || loadConfig().apiKey;\n}\n\nexport function getBaseUrl(): string {\n return process.env.ANONLI_BASE_URL || loadConfig().baseUrl;\n}\n\nexport function setApiKey(key: string): void {\n const config = loadConfig();\n config.apiKey = key;\n saveConfig(config);\n}\n\nexport function removeApiKey(): void {\n const config = loadConfig();\n delete config.apiKey;\n delete config.userEmail;\n delete config.userName;\n saveConfig(config);\n}\n\nexport function setUserInfo(email: string, name: string | null): void {\n const config = loadConfig();\n config.userEmail = email;\n config.userName = name;\n saveConfig(config);\n}\n\nexport function getUserInfo(): { email: string; name: string | null } | null {\n const config = loadConfig();\n if (!config.userEmail) return null;\n return { email: config.userEmail, name: config.userName ?? null };\n}\n\nexport function maskApiKey(key: string): string {\n if (key.length <= 8) return \"****\";\n return key.slice(0, 6) + \"...\" + key.slice(-4);\n}\n","// Fine-grained exit codes (F7)\nexport const EXIT_SUCCESS = 0;\nexport const EXIT_ERROR = 1;\nexport const EXIT_AUTH = 2;\nexport const EXIT_RATE_LIMIT = 3;\nexport const EXIT_PLAN_LIMIT = 4;\nexport const EXIT_NOT_FOUND = 5;\nexport const EXIT_VALIDATION = 6;\n\nexport class CliError extends Error {\n constructor(\n message: string,\n public readonly exitCode: number = EXIT_ERROR\n ) {\n super(message);\n this.name = \"CliError\";\n }\n}\n\nexport class AuthError extends CliError {\n constructor(message: string = \"Not authenticated. Run `anonli login` first.\") {\n super(message, EXIT_AUTH);\n this.name = \"AuthError\";\n }\n}\n\nexport class ApiError extends CliError {\n public readonly statusCode: number;\n public readonly code?: string;\n public readonly requestId?: string;\n\n constructor(\n message: string,\n statusCode: number,\n code?: string,\n requestId?: string\n ) {\n const exitCode =\n statusCode === 404 ? EXIT_NOT_FOUND :\n statusCode === 429 ? EXIT_RATE_LIMIT :\n statusCode === 402 || statusCode === 403 ? EXIT_PLAN_LIMIT :\n EXIT_ERROR;\n super(message, exitCode);\n this.name = \"ApiError\";\n this.statusCode = statusCode;\n this.code = code;\n this.requestId = requestId;\n }\n}\n\nexport class RateLimitError extends ApiError {\n constructor(\n message: string,\n public readonly resetAt: Date\n ) {\n super(message, 429, \"RATE_LIMITED\");\n this.name = \"RateLimitError\";\n }\n}\n\nexport class PlanLimitError extends CliError {\n constructor(message: string, public readonly suggestion: string) {\n super(message, EXIT_PLAN_LIMIT);\n this.name = \"PlanLimitError\";\n }\n}\n\nexport class ValidationError extends CliError {\n constructor(message: string) {\n super(message, EXIT_VALIDATION);\n this.name = \"ValidationError\";\n }\n}\n","{\n \"name\": \"anonli\",\n \"version\": \"1.0.0\",\n \"description\": \"anon.li CLI - encrypted file drops and anonymous email aliases\",\n \"type\": \"module\",\n \"license\": \"AGPL-3.0\",\n \"author\": \"anon.li\",\n \"homepage\": \"https://anon.li\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/anondotli/cli\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/anondotli/cli/issues\"\n },\n \"keywords\": [\n \"cli\",\n \"encrypted\",\n \"file-sharing\",\n \"email\",\n \"alias\",\n \"privacy\",\n \"private\",\n \"anonymous\",\n \"e2ee\"\n ],\n \"bin\": {\n \"anonli\": \"./bin/anonli.js\"\n },\n \"files\": [\n \"bin\",\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"dependencies\": {\n \"boxen\": \"^8.0.1\",\n \"chalk\": \"^5.6.2\",\n \"cli-progress\": \"^3.12.0\",\n \"cli-table3\": \"^0.6.5\",\n \"commander\": \"^13.1.0\",\n \"figures\": \"^6.1.0\",\n \"hash-wasm\": \"^4.12.0\",\n \"mime-types\": \"^2.1.35\",\n \"ora\": \"^8.2.0\",\n \"semver\": \"^7.7.4\",\n \"terminal-link\": \"^3.0.0\"\n },\n \"devDependencies\": {\n \"@types/cli-progress\": \"^3.11.6\",\n \"@types/mime-types\": \"^2.1.4\",\n \"@types/node\": \"^22.19.15\",\n \"@types/semver\": \"^7.7.1\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^5.9.3\"\n },\n \"engines\": {\n \"node\": \">=18\"\n }\n}","/** 1 Megabyte in bytes */\nexport const MB = 1024 * 1024;\n\n/** 1 Gigabyte in bytes */\nexport const GB = 1024 * MB;\n\n/** Maximum chunks per file */\nexport const MAX_CHUNKS_PER_FILE = 100;\n\n/** Minimum chunk size (50 MB) */\nexport const MIN_CHUNK_SIZE = 50 * MB;\n\n/** File size threshold: 1 GB */\nexport const FILE_SIZE_THRESHOLD_1GB = 1 * GB;\n\n/** Argon2id parameters for password key derivation (OWASP recommended) */\nexport const ARGON2_MEMORY = 65536; // 64 MiB\nexport const ARGON2_TIME = 3; // iterations\nexport const ARGON2_PARALLELISM = 1;\nexport const ARGON2_HASH_LENGTH = 32; // bytes (AES-256 key)\n\n/** AES-GCM authentication tag size in bytes */\nexport const AUTH_TAG_SIZE = 16;\n\n/** IV length in bytes */\nexport const IV_LENGTH = 12;\n\n/** Salt length in bytes */\nexport const SALT_LENGTH = 32;\n\n/** CLI version — read from package.json (single source of truth) */\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nexport const CLI_VERSION: string = require(\"../../package.json\").version;\n\n/** Max retry attempts */\nexport const MAX_RETRIES = 3;\n\n/** Base delay for exponential backoff (ms) */\nexport const RETRY_BASE_DELAY = 1000;\n","import { getApiKey, getBaseUrl } from \"./config.js\";\nimport { ApiError, AuthError, RateLimitError } from \"./errors.js\";\nimport { MAX_RETRIES, RETRY_BASE_DELAY, CLI_VERSION } from \"./constants.js\";\nimport type {\n ApiSuccessResponse,\n ApiListResponse,\n ApiErrorResponse,\n RateLimitInfo,\n} from \"../types/api.js\";\n\n// Actionable messages for known API error codes (U4)\nconst CODE_MESSAGES: Record<string, string> = {\n NOT_FOUND: \"Resource not found — it may have expired or been deleted\",\n QUOTA_EXCEEDED: \"Storage limit reached — upgrade at anon.li/dashboard\",\n FORBIDDEN: \"This feature requires a paid plan — see `anonli subscribe`\",\n UNAUTHORIZED: \"Invalid or expired API key — run `anonli login` to re-authenticate\",\n};\n\nfunction getHeaders(): Record<string, string> {\n const apiKey = getApiKey();\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"User-Agent\": `anonli-cli/${CLI_VERSION}`,\n };\n\n if (apiKey) {\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n\n return headers;\n}\n\nexport function extractRateLimit(res: Response): RateLimitInfo | undefined {\n const limit = res.headers.get(\"X-RateLimit-Limit\");\n const remaining = res.headers.get(\"X-RateLimit-Remaining\");\n const reset = res.headers.get(\"X-RateLimit-Reset\");\n\n if (limit && remaining && reset) {\n return {\n limit: parseInt(limit, 10),\n remaining: parseInt(remaining, 10),\n reset: parseInt(reset, 10),\n };\n }\n return undefined;\n}\n\nasync function handleError(res: Response): Promise<never> {\n let body: ApiErrorResponse | { error: string } | undefined;\n try {\n body = (await res.json()) as ApiErrorResponse | { error: string };\n } catch {\n // No JSON body\n }\n\n if (res.status === 401) {\n const rawMsg =\n (body && \"error\" in body && typeof body.error === \"string\"\n ? body.error\n : (body as ApiErrorResponse)?.error?.message) || \"Unauthorized\";\n throw new AuthError(CODE_MESSAGES[\"UNAUTHORIZED\"] ?? rawMsg);\n }\n\n if (res.status === 429) {\n const resetHeader = res.headers.get(\"X-RateLimit-Reset\");\n const resetDate = resetHeader\n ? new Date(parseInt(resetHeader, 10))\n : new Date(Date.now() + 60_000);\n throw new RateLimitError(\n (body as ApiErrorResponse)?.error?.message || \"Rate limit exceeded\",\n resetDate\n );\n }\n\n const apiCode = (body as ApiErrorResponse)?.error?.code;\n const rawMessage =\n (body && \"error\" in body && typeof body.error === \"object\"\n ? (body as ApiErrorResponse).error.message\n : (body as { error: string })?.error) ||\n `Request failed with status ${res.status}`;\n\n // Use friendly message if available for this code\n const message = (apiCode && CODE_MESSAGES[apiCode]) || rawMessage;\n\n throw new ApiError(\n message,\n res.status,\n apiCode,\n (body as ApiErrorResponse)?.meta?.request_id\n );\n}\n\nasync function fetchWithRetry(\n url: string,\n options: RequestInit,\n retries = MAX_RETRIES\n): Promise<Response> {\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const res = await fetch(url, options);\n\n // Don't retry client errors\n if (res.status >= 400 && res.status < 500) {\n return res;\n }\n\n // Retry server errors\n if (res.status >= 500 && attempt < retries) {\n await delay(RETRY_BASE_DELAY * Math.pow(2, attempt));\n continue;\n }\n\n return res;\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n\n if (lastError.name === \"AbortError\") {\n throw lastError;\n }\n\n if (attempt < retries) {\n await delay(RETRY_BASE_DELAY * Math.pow(2, attempt));\n continue;\n }\n }\n }\n\n throw lastError || new Error(\"Request failed after retries\");\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport interface ApiResult<T> {\n data: T;\n rateLimit?: RateLimitInfo;\n}\n\nexport interface ApiListResult<T> {\n data: T[];\n total: number;\n rateLimit?: RateLimitInfo;\n meta?: Record<string, unknown>;\n}\n\nexport async function apiGet<T>(\n path: string,\n retry = true\n): Promise<ApiResult<T>> {\n const url = `${getBaseUrl()}${path}`;\n const res = retry\n ? await fetchWithRetry(url, { method: \"GET\", headers: getHeaders() })\n : await fetch(url, { method: \"GET\", headers: getHeaders() });\n\n if (!res.ok) await handleError(res);\n\n const rateLimit = extractRateLimit(res);\n const json = (await res.json()) as ApiSuccessResponse<T>;\n return { data: json.data, rateLimit };\n}\n\nexport async function apiGetList<T>(\n path: string\n): Promise<ApiListResult<T>> {\n const url = `${getBaseUrl()}${path}`;\n const res = await fetchWithRetry(url, {\n method: \"GET\",\n headers: getHeaders(),\n });\n\n if (!res.ok) await handleError(res);\n\n const rateLimit = extractRateLimit(res);\n const json = (await res.json()) as ApiListResponse<T>;\n return {\n data: json.data,\n total: json.meta.total,\n rateLimit,\n meta: json.meta as unknown as Record<string, unknown>,\n };\n}\n\nexport async function apiPost<T>(\n path: string,\n body?: unknown\n): Promise<ApiResult<T>> {\n const url = `${getBaseUrl()}${path}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: getHeaders(),\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n\n if (!res.ok) await handleError(res);\n\n const rateLimit = extractRateLimit(res);\n const json = (await res.json()) as ApiSuccessResponse<T>;\n return { data: json.data, rateLimit };\n}\n\nexport async function apiPatch<T>(\n path: string,\n body?: unknown\n): Promise<ApiResult<T>> {\n const url = `${getBaseUrl()}${path}`;\n const res = await fetch(url, {\n method: \"PATCH\",\n headers: getHeaders(),\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n\n if (!res.ok) await handleError(res);\n\n const rateLimit = extractRateLimit(res);\n const json = (await res.json()) as ApiSuccessResponse<T>;\n return { data: json.data, rateLimit };\n}\n\nexport async function apiDelete(path: string): Promise<{ rateLimit?: RateLimitInfo }> {\n const url = `${getBaseUrl()}${path}`;\n const res = await fetch(url, {\n method: \"DELETE\",\n headers: getHeaders(),\n });\n\n if (!res.ok) await handleError(res);\n\n return { rateLimit: extractRateLimit(res) };\n}\n\nexport async function apiRawFetch(\n url: string,\n options: RequestInit\n): Promise<Response> {\n return fetch(url, options);\n}\n\nexport async function apiFetch(\n path: string,\n options: RequestInit = {}\n): Promise<Response> {\n const url = `${getBaseUrl()}${path}`;\n return fetch(url, {\n ...options,\n headers: {\n ...getHeaders(),\n ...(options.headers as Record<string, string>),\n },\n });\n}\n\nexport function requireAuth(): void {\n if (!getApiKey()) {\n throw new AuthError();\n }\n}\n","import { Command } from \"commander\";\nimport { loginCommand } from \"./commands/login.js\";\nimport { logoutCommand } from \"./commands/logout.js\";\nimport { whoamiCommand } from \"./commands/whoami.js\";\nimport { dropCommand } from \"./commands/drop.js\";\nimport { aliasCommand } from \"./commands/alias.js\";\nimport { recipientCommand } from \"./commands/recipient.js\";\nimport { domainCommand } from \"./commands/domain.js\";\nimport { apikeyCommand } from \"./commands/apikey.js\";\nimport { configCommand } from \"./commands/config-cmd.js\";\nimport { updateCommand } from \"./commands/update.js\";\nimport { subscribeCommand } from \"./commands/subscribe.js\";\nimport { completionsCommand } from \"./commands/completions.js\";\nimport { checkForUpdates } from \"./lib/version-check.js\";\nimport { AuthError, CliError, PlanLimitError } from \"./lib/errors.js\";\nimport { createHelpConfig } from \"./lib/brand.js\";\nimport { CLI_VERSION } from \"./lib/constants.js\";\nimport { getApiKey } from \"./lib/config.js\";\nimport { runAuthFlow } from \"./lib/auth.js\";\nimport * as ui from \"./lib/ui.js\";\n\nconst VERSION = CLI_VERSION;\n\nconst helpConfig = createHelpConfig(VERSION);\n\nconst program = new Command()\n .name(\"anonli\")\n .description(\"anon.li CLI - encrypted file drops & anonymous email aliases\")\n .version(VERSION, \"-v, --version\")\n // U2: Global quiet flag\n .option(\"-q, --quiet\", \"Suppress all non-essential output (spinners, tables, boxes)\")\n .configureHelp(helpConfig);\n\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\nprogram.addCommand(whoamiCommand);\nprogram.addCommand(dropCommand);\nprogram.addCommand(aliasCommand);\nprogram.addCommand(recipientCommand);\nprogram.addCommand(domainCommand);\nprogram.addCommand(apikeyCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(updateCommand);\nprogram.addCommand(subscribeCommand);\nprogram.addCommand(completionsCommand);\n\n// .addCommand() doesn't inherit settings - apply recursively\nprogram.exitOverride();\nfunction propagateSettings(cmd: Command) {\n for (const sub of cmd.commands) {\n sub.configureHelp(helpConfig);\n sub.exitOverride();\n propagateSettings(sub);\n }\n}\npropagateSettings(program);\n\n// Commands that don't require authentication\nconst AUTH_EXEMPT = new Set([\n \"login\",\n \"logout\",\n \"config\",\n \"update\",\n \"completions\",\n \"drop info\",\n \"drop get\",\n \"drop download\",\n \"drop dl\",\n \"drop share\",\n]);\n\n// Auto-auth: prompt for API key when missing before authenticated commands\nprogram.hook(\"preAction\", async (thisCommand, actionCommand) => {\n // U2: Apply quiet mode from root program options\n const rootOpts = program.opts();\n if (rootOpts.quiet) {\n ui.setQuiet(true);\n }\n\n // Build the full command path (e.g. \"drop upload\", \"alias list\")\n const parts: string[] = [];\n let cmd: Command | null = actionCommand;\n while (cmd && cmd !== program) {\n parts.unshift(cmd.name());\n cmd = cmd.parent;\n }\n const commandPath = parts.join(\" \");\n\n // Skip auth check for exempt commands\n if (AUTH_EXEMPT.has(commandPath)) return;\n\n // Already authenticated\n if (getApiKey()) return;\n\n // Non-TTY: throw with env var hint\n if (!process.stdin.isTTY) {\n throw new AuthError(\n \"Not authenticated. Set ANONLI_API_KEY or run `anonli login` interactively.\"\n );\n }\n\n // TTY: run interactive auth flow\n ui.warn(\"Authentication required. Let's set up your API key.\");\n ui.spacer();\n const success = await runAuthFlow();\n if (!success) {\n throw new AuthError(\"Authentication failed.\");\n }\n ui.spacer();\n});\n\n// Version check after each command\nprogram.hook(\"postAction\", async () => {\n await checkForUpdates(VERSION).catch(() => {\n // Silently ignore\n });\n});\n\nasync function main() {\n try {\n await program.parseAsync(process.argv);\n } catch (err) {\n // F7: Use typed exit codes from error classes\n if (err instanceof PlanLimitError) {\n ui.errorBox(\"Plan Limit\", err.message, err.suggestion);\n process.exit(err.exitCode);\n }\n if (err instanceof AuthError) {\n ui.error(err.message);\n process.exit(err.exitCode);\n }\n if (err instanceof CliError) {\n // Message already printed by the command\n process.exit(err.exitCode);\n }\n // Commander exit override throws on help/version/missing subcommand\n const code = (err as Record<string, unknown>)?.code;\n if (typeof code === \"string\" && code.startsWith(\"commander.\")) {\n process.exit(0);\n }\n // Unexpected error\n if (err instanceof Error) {\n console.error(`Error: ${err.message}`);\n }\n process.exit(1);\n }\n}\n\nmain();\n","import { Command } from \"commander\";\nimport { runAuthFlow } from \"../lib/auth.js\";\nimport { getApiKey } from \"../lib/config.js\";\nimport * as ui from \"../lib/ui.js\";\n\nexport const loginCommand = new Command(\"login\")\n .description(\"Authenticate with your API key\")\n .option(\"--token <key>\", \"API key (or enter interactively)\")\n .action(async (options) => {\n if (getApiKey()) {\n ui.errorBox(\n \"Already Logged In\",\n \"You are already authenticated.\",\n \"Run `anonli logout` first, then try again.\"\n );\n process.exit(1);\n }\n\n const success = await runAuthFlow(options.token as string | undefined);\n if (!success) {\n process.exit(1);\n }\n });\n","import { setApiKey, removeApiKey, setUserInfo } from \"./config.js\";\nimport { apiGet } from \"./api.js\";\nimport * as ui from \"./ui.js\";\nimport type { MeResponse } from \"../types/api.js\";\n\n/**\n * Run the interactive auth flow. Prompts for an API key (masked) if none\n * is provided and stdin is a TTY, validates it against /api/v1/me, and\n * persists it on success.\n *\n * @returns `true` on successful authentication, `false` on failure.\n */\nexport async function runAuthFlow(token?: string): Promise<boolean> {\n let apiKey = token;\n\n if (!apiKey) {\n ui.info(\n `Get your API key from ${ui.link(\"https://anon.li/dashboard/settings/api\")}`\n );\n ui.spacer();\n apiKey = await ui.prompt(\"API key:\", { mask: true });\n }\n\n if (!apiKey) {\n ui.error(\"No API key provided.\");\n return false;\n }\n\n if (!apiKey.startsWith(\"ak_\")) {\n ui.errorBox(\n \"Invalid Key\",\n 'API keys start with \"ak_\".',\n \"Get your key at https://anon.li/dashboard/settings/api\"\n );\n return false;\n }\n\n const spin = ui.spinner(\"Validating API key...\");\n\n try {\n setApiKey(apiKey);\n const result = await apiGet<MeResponse>(\"/api/v1/me\");\n spin.stop();\n\n // Cache user info for home screen greeting\n setUserInfo(result.data.email, result.data.name);\n\n const badge = ui.tierBadge(result.data.tier, result.data.product);\n ui.successBox(\n \"Authenticated\",\n `Logged in as ${ui.c.accent(result.data.email)} ${badge}`\n );\n ui.showRateLimit(result.rateLimit);\n return true;\n } catch (err) {\n removeApiKey();\n spin.stop();\n ui.errorBox(\n \"Authentication Failed\",\n err instanceof Error ? err.message : \"Invalid API key.\",\n \"Get your key at https://anon.li/dashboard/settings/api\"\n );\n return false;\n }\n}\n","import chalk from \"chalk\";\nimport ora, { type Ora } from \"ora\";\nimport cliProgress from \"cli-progress\";\nimport figures from \"figures\";\nimport boxen from \"boxen\";\nimport Table from \"cli-table3\";\nimport terminalLink from \"terminal-link\";\nimport readline from \"node:readline\";\nimport { c } from \"./theme.js\";\nimport { printHeader } from \"./brand.js\";\nimport type { RateLimitInfo } from \"../types/api.js\";\n\n// Re-export theme for direct access from commands\nexport { c, brandColor } from \"./theme.js\";\n\n// ─── Quiet Mode (U2) ──────────────────────────────────────\n\nlet _quiet = false;\n\nexport function setQuiet(val: boolean): void {\n _quiet = val;\n}\n\nexport function isQuiet(): boolean {\n return _quiet;\n}\n\n// ─── JSON Output (U1) ─────────────────────────────────────\n\nexport function outputJson(data: unknown): void {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n}\n\n// ─── Spinner ──────────────────────────────────────────────\n\nexport function spinner(text: string): Ora {\n return ora({\n text: c.secondary(text),\n color: \"magenta\",\n isSilent: _quiet,\n }).start();\n}\n\n// ─── Status Messages ──────────────────────────────────────\n\nexport function success(message: string): void {\n if (_quiet) return;\n console.log(c.success(figures.tick) + \" \" + c.primary(message));\n}\n\nexport function error(message: string): void {\n // Errors always go to stderr, even in quiet mode\n console.error(c.error(figures.cross) + \" \" + c.primary(message));\n}\n\nexport function warn(message: string): void {\n if (_quiet) return;\n console.log(c.warning(figures.warning) + \" \" + c.secondary(message));\n}\n\nexport function info(message: string): void {\n if (_quiet) return;\n console.log(c.info(figures.info) + \" \" + c.secondary(message));\n}\n\n// ─── Text Formatting ──────────────────────────────────────\n\nexport function dim(text: string): string {\n return c.muted(text);\n}\n\nexport function bold(text: string): string {\n return c.primary(chalk.bold(text));\n}\n\nexport function link(url: string): string {\n return terminalLink(c.link(url), url, {\n fallback: () => c.link(url),\n });\n}\n\n// ─── Layout ───────────────────────────────────────────────\n\nexport function header(title: string): void {\n if (_quiet) return;\n console.log(printHeader(title));\n}\n\nexport function divider(): void {\n if (_quiet) return;\n console.log(c.subtle(\"─\".repeat(48)));\n}\n\nexport function spacer(): void {\n if (_quiet) return;\n console.log();\n}\n\nexport function keyValue(label: string, value: string, indent = 2): void {\n if (_quiet) return;\n const pad = \" \".repeat(indent);\n console.log(`${pad}${c.secondary(label + \":\")} ${c.primary(value)}`);\n}\n\nexport function sectionTitle(title: string): void {\n if (_quiet) return;\n console.log(c.secondary(chalk.bold(title)));\n}\n\n// ─── Boxes ────────────────────────────────────────────────\n\nexport function successBox(title: string, content: string): void {\n if (_quiet) return;\n console.log(\n boxen(content, {\n title: c.success(figures.tick + \" \" + title),\n titleAlignment: \"left\",\n borderStyle: \"round\",\n borderColor: \"#10B981\",\n padding: { top: 0, bottom: 0, left: 1, right: 1 },\n margin: { top: 1, bottom: 0, left: 0, right: 0 },\n })\n );\n}\n\nexport function errorBox(\n title: string,\n message: string,\n suggestion?: string\n): void {\n let content = c.primary(message);\n if (suggestion) {\n content += \"\\n\" + c.muted(suggestion);\n }\n // Error boxes always show (not suppressed by quiet)\n console.log(\n boxen(content, {\n title: c.error(figures.cross + \" \" + title),\n titleAlignment: \"left\",\n borderStyle: \"round\",\n borderColor: \"#EF4444\",\n padding: { top: 0, bottom: 0, left: 1, right: 1 },\n margin: { top: 1, bottom: 0, left: 0, right: 0 },\n })\n );\n}\n\nexport function box(\n content: string,\n opts?: { title?: string; borderColor?: string }\n): void {\n if (_quiet) return;\n console.log(\n boxen(content, {\n title: opts?.title,\n titleAlignment: \"left\",\n borderStyle: \"round\",\n borderColor: (opts?.borderColor || \"#334155\") as string,\n padding: { top: 0, bottom: 0, left: 1, right: 1 },\n margin: { top: 1, bottom: 0, left: 0, right: 0 },\n })\n );\n}\n\n// ─── Prompts ──────────────────────────────────────────────\n\nexport function confirm(prompt: string): Promise<boolean> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n const styled = `${c.warning(figures.warning)} ${c.primary(prompt)} ${c.muted(\"[y/N]\")} `;\n rl.question(styled, (answer) => {\n rl.close();\n resolve(answer.toLowerCase() === \"y\");\n });\n });\n}\n\nexport function prompt(\n question: string,\n opts?: { mask?: boolean }\n): Promise<string> {\n const styled = `${c.info(figures.pointer)} ${c.primary(question)} `;\n\n if (!opts?.mask) {\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question(styled, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n }\n\n // Masked input: use raw mode for correct star echo + backspace handling\n return new Promise((resolve) => {\n process.stdout.write(styled);\n const stdin = process.stdin;\n\n if (!stdin.isTTY) {\n // Non-TTY fallback (piped input): read a line silently\n const rl = readline.createInterface({ input: stdin });\n rl.once(\"line\", (line) => {\n rl.close();\n console.log();\n resolve(line.trim());\n });\n return;\n }\n\n const wasRaw = stdin.isRaw;\n stdin.setRawMode(true);\n stdin.resume();\n stdin.setEncoding(\"utf8\");\n\n let input = \"\";\n const onData = (data: string) => {\n for (const ch of data) {\n if (ch === \"\\r\" || ch === \"\\n\") {\n stdin.setRawMode(wasRaw);\n stdin.removeListener(\"data\", onData);\n stdin.pause();\n console.log();\n resolve(input.trim());\n return;\n } else if (ch === \"\\u0003\") {\n // Ctrl+C\n stdin.setRawMode(wasRaw);\n stdin.removeListener(\"data\", onData);\n stdin.pause();\n console.log();\n process.exit(0);\n return;\n } else if (ch === \"\\u007f\" || ch === \"\\b\") {\n // Backspace\n if (input.length > 0) {\n input = input.slice(0, -1);\n process.stdout.write(\"\\b \\b\");\n }\n } else if (ch.charCodeAt(0) >= 32) {\n input += ch;\n process.stdout.write(c.muted(\"*\"));\n }\n }\n };\n\n stdin.on(\"data\", onData);\n });\n}\n\n// ─── Usage Bars ──────────────────────────────────────────\n\nexport function usageBar(used: number, limit: number, width = 12): string {\n if (limit === 0) {\n return used > 0 ? c.error(\"▓\".repeat(width)) : c.subtle(\"░\".repeat(width));\n }\n const ratio = Math.min(used / limit, 1);\n const filled = Math.round(ratio * width);\n const empty = width - filled;\n\n let colorFn = c.success;\n if (used > limit) colorFn = c.error;\n else if (ratio >= 0.9) colorFn = c.warning;\n else if (ratio >= 0.7) colorFn = c.warning;\n\n return colorFn(\"▓\".repeat(filled)) + c.subtle(\"░\".repeat(empty));\n}\n\nexport function usageRow(\n label: string,\n used: number,\n limit?: number,\n opts?: { labelWidth?: number; barWidth?: number }\n): void {\n if (_quiet) return;\n const labelWidth = opts?.labelWidth ?? 14;\n const barWidth = opts?.barWidth ?? 12;\n const pad = \" \";\n const paddedLabel = c.secondary((label + \":\").padEnd(labelWidth));\n\n if (limit === undefined) {\n console.log(`${pad}${paddedLabel} ${c.primary(String(used))}`);\n return;\n }\n\n const bar = usageBar(used, limit, barWidth);\n const count = `${used}/${limit}`;\n const overLimit = used > limit;\n const countStr = overLimit ? c.error(count) : c.primary(count);\n const warnStr = overLimit ? \" \" + c.warning(\"▲\") : \"\";\n console.log(`${pad}${paddedLabel} ${bar} ${countStr}${warnStr}`);\n}\n\nexport function storageRow(\n label: string,\n used: number,\n limit: number,\n opts?: { labelWidth?: number; barWidth?: number }\n): void {\n if (_quiet) return;\n const labelWidth = opts?.labelWidth ?? 14;\n const barWidth = opts?.barWidth ?? 12;\n const pad = \" \";\n const paddedLabel = c.secondary((label + \":\").padEnd(labelWidth));\n const bar = usageBar(used, limit, barWidth);\n console.log(\n `${pad}${paddedLabel} ${bar} ${c.primary(formatBytes(used))}${c.muted(\"/\")}${c.primary(formatBytes(limit))}`\n );\n}\n\n// ─── Badges ───────────────────────────────────────────────\n\nexport function statusBadge(\n label: string,\n variant: \"active\" | \"inactive\"\n): string {\n if (variant === \"active\") {\n return c.success(\"●\") + \" \" + c.success(label);\n }\n return c.error(\"○\") + \" \" + c.error(label);\n}\n\nexport function tierBadge(tier: string, product?: string | null): string {\n const t = tier.toLowerCase();\n const productLabel = product ? ` (${product.charAt(0).toUpperCase() + product.slice(1)})` : \"\";\n if (t === \"pro\") return c.gold(chalk.bold(\"PRO\")) + c.muted(productLabel);\n if (t === \"plus\") return c.accent(chalk.bold(\"PLUS\")) + c.muted(productLabel);\n return c.muted(\"Free\");\n}\n\n// ─── Progress Bar ─────────────────────────────────────────\n\nexport function progressBar(\n total: number,\n label: string\n): cliProgress.SingleBar {\n const bar = new cliProgress.SingleBar(\n {\n format: ` ${c.secondary(label)} ${chalk.hex(\"#8B5CF6\")(\"{bar}\")} ${c.primary(\"{percentage}%\")} ${c.subtle(\"┃\")} ${c.muted(\"{value}/{total}\")}`,\n barCompleteChar: \"━\",\n barIncompleteChar: chalk.hex(\"#334155\")(\"━\"),\n hideCursor: true,\n noTTYOutput: _quiet,\n },\n cliProgress.Presets.shades_classic\n );\n bar.start(total, 0);\n return bar;\n}\n\n// ─── Rate Limit ───────────────────────────────────────────\n\nexport function showRateLimit(rateLimit?: RateLimitInfo): void {\n if (!rateLimit || _quiet) return;\n console.log(\n c.subtle(\n ` ${figures.bullet} API: ${rateLimit.remaining}/${rateLimit.limit} requests remaining`\n )\n );\n}\n\n// ─── Table ────────────────────────────────────────────────\n\nexport function table(headers: string[], rows: string[][]): void {\n if (_quiet) return;\n const t = new Table({\n head: headers.map((h) => c.secondary(chalk.bold(h))),\n chars: {\n top: c.subtle(\"─\"),\n \"top-mid\": c.subtle(\"┬\"),\n \"top-left\": c.subtle(\"╭\"),\n \"top-right\": c.subtle(\"╮\"),\n bottom: c.subtle(\"─\"),\n \"bottom-mid\": c.subtle(\"┴\"),\n \"bottom-left\": c.subtle(\"╰\"),\n \"bottom-right\": c.subtle(\"╯\"),\n left: c.subtle(\"│\"),\n \"left-mid\": c.subtle(\"├\"),\n mid: c.subtle(\"─\"),\n \"mid-mid\": c.subtle(\"┼\"),\n right: c.subtle(\"│\"),\n \"right-mid\": c.subtle(\"┤\"),\n middle: c.subtle(\"│\"),\n },\n style: {\n head: [],\n border: [],\n \"padding-left\": 1,\n \"padding-right\": 1,\n },\n });\n\n for (const row of rows) {\n t.push(row);\n }\n\n console.log(t.toString());\n}\n\n// ─── Update Notice ────────────────────────────────────────\n\nexport function updateNotice(current: string, latest: string): void {\n if (_quiet) return;\n const content = [\n `${c.muted(\"Current:\")} ${c.primary(current)} ${c.muted(\"→\")} ${c.muted(\"Latest:\")} ${c.success(latest)}`,\n \"\",\n `${c.secondary('Run')} ${c.accent(\"anonli update\")} ${c.secondary('to upgrade')}`,\n ].join(\"\\n\");\n\n console.log(\n boxen(content, {\n title: c.warning(figures.warning + \" Update Available\"),\n titleAlignment: \"left\",\n borderStyle: \"round\",\n borderColor: \"#F59E0B\",\n padding: { top: 0, bottom: 0, left: 1, right: 1 },\n margin: { top: 1, bottom: 0, left: 0, right: 0 },\n })\n );\n}\n\n// ─── Formatters ───────────────────────────────────────────\n\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + \" \" + sizes[i];\n}\n\nexport function formatDate(iso: string): string {\n return new Date(iso).toLocaleDateString(\"en-US\", {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\nexport function formatDays(days: number): string {\n if (days === 1) return \"24 hours\";\n return `${days} days`;\n}\n\nexport function alignedKeyValue(label: string, value: string, labelWidth = 18, indent = 2): void {\n if (_quiet) return;\n const pad = \" \".repeat(indent);\n const paddedLabel = (label + \":\").padEnd(labelWidth);\n console.log(`${pad}${c.secondary(paddedLabel)} ${c.primary(value)}`);\n}\n","import chalk from \"chalk\";\n\n// Honor NO_COLOR (https://no-color.org/) and dumb terminals (U3)\nif (process.env.NO_COLOR !== undefined || process.env.TERM === \"dumb\") {\n chalk.level = 0;\n}\n\n// Brand color: blue\nconst blue = chalk.hex(\"#6366F1\");\nexport const brandColor: { (str: string): string; multiline(str: string): string } =\n Object.assign(\n (str: string) => blue(str),\n { multiline: (str: string) => str.split(\"\\n\").map((line) => blue(line)).join(\"\\n\") },\n );\n\n// Pre-built chalk instances for the brand palette\nexport const c = {\n // Status\n success: chalk.hex(\"#10B981\"),\n error: chalk.hex(\"#EF4444\"),\n warning: chalk.hex(\"#F59E0B\"),\n info: chalk.hex(\"#8B5CF6\"),\n\n // Text hierarchy\n primary: chalk.hex(\"#F8FAFC\"),\n secondary: chalk.hex(\"#94A3B8\"),\n muted: chalk.hex(\"#64748B\"),\n subtle: chalk.hex(\"#475569\"),\n\n // Accents\n accent: chalk.hex(\"#A78BFA\"),\n link: chalk.hex(\"#22D3EE\"),\n gold: chalk.hex(\"#FBBF24\"),\n\n // Borders\n border: chalk.hex(\"#334155\"),\n};\n","import type { Command, Help } from \"commander\";\nimport { brandColor, c } from \"./theme.js\";\nimport { getApiKey, getUserInfo } from \"./config.js\";\n\nconst LOGO = `\n __ _ _ __ ___ _ __ | (_)\n / _\\` | '_ \\\\ / _ \\\\| '_ \\\\ | | |\n | (_| | | | | (_) | | | |_| | |\n \\\\__,_|_| |_|\\\\___/|_| |_(_)_|_|`;\n\nexport function printBanner(version: string): string {\n const logo = brandColor.multiline(LOGO.slice(1)); // trim leading newline\n const tagline = c.secondary(\" Encrypted drops & anonymous aliases\") + c.muted(` v${version}`);\n\n let greeting = \"\";\n if (getApiKey()) {\n const info = getUserInfo();\n if (info) {\n const displayName = info.name\n ? info.name.split(\" \")[0]\n : info.email.split(\"@\")[0];\n greeting = \"\\n \" + c.secondary(\"Welcome back, \") + c.primary(displayName) + c.secondary(\"!\");\n }\n }\n\n return `\\n${logo}\\n${tagline}${greeting}\\n`;\n}\n\nexport function printHeader(commandName: string): string {\n const name = brandColor(\"anon.li\");\n const arrow = c.muted(\" > \");\n const cmd = c.primary(commandName);\n const divider = c.subtle(\"─\".repeat(48));\n return `${name}${arrow}${cmd}\\n${divider}`;\n}\n\nfunction getCommandPath(cmd: Command): string {\n const parts: string[] = [];\n let current: Command | null = cmd;\n while (current) {\n if (current.parent) {\n parts.unshift(current.name());\n }\n current = current.parent;\n }\n return parts.join(\" \");\n}\n\nexport function createHelpConfig(version: string): Partial<Help> {\n return {\n formatHelp(cmd: Command, helper: Help): string {\n const isRoot = !cmd.parent;\n let output = \"\";\n\n // Header\n if (isRoot) {\n output += printBanner(version) + \"\\n\";\n } else {\n output += printHeader(getCommandPath(cmd)) + \"\\n\\n\";\n }\n\n // Description\n const desc = helper.commandDescription(cmd);\n if (desc && !isRoot) {\n output += ` ${c.secondary(desc)}\\n\\n`;\n }\n\n // Usage\n const usage = helper.commandUsage(cmd);\n output += ` ${c.muted(\"Usage\")}\\n`;\n output += ` ${c.subtle(\"$\")} ${c.primary(usage)}\\n`;\n\n // Arguments\n const args = helper.visibleArguments(cmd);\n if (args.length > 0) {\n const termLen = helper.longestArgumentTermLength(cmd, helper);\n output += `\\n ${c.muted(\"Arguments\")}\\n`;\n for (const arg of args) {\n const term = helper.argumentTerm(arg);\n const desc = helper.argumentDescription(arg);\n output += ` ${c.accent(term.padEnd(termLen + 2))} ${c.secondary(desc)}\\n`;\n }\n }\n\n // Commands (filter out implicit 'help' subcommand)\n const cmds = helper.visibleCommands(cmd).filter(\n (sub: Command) => sub.name() !== \"help\"\n );\n if (cmds.length > 0) {\n let maxLen = 0;\n const items = cmds.map((sub: Command) => {\n const term = helper.subcommandTerm(sub);\n if (term.length > maxLen) maxLen = term.length;\n return { term, desc: helper.subcommandDescription(sub) };\n });\n output += `\\n ${c.muted(\"Commands\")}\\n`;\n for (const { term, desc } of items) {\n output += ` ${c.accent(term.padEnd(maxLen + 2))} ${c.secondary(desc)}\\n`;\n }\n }\n\n // Options\n const opts = helper.visibleOptions(cmd);\n if (opts.length > 0) {\n const termLen = helper.longestOptionTermLength(cmd, helper);\n output += `\\n ${c.muted(\"Options\")}\\n`;\n for (const opt of opts) {\n const term = helper.optionTerm(opt);\n const desc = helper.optionDescription(opt);\n output += ` ${c.accent(term.padEnd(termLen + 2))} ${c.secondary(desc)}\\n`;\n }\n }\n\n output += \"\\n\";\n return output;\n },\n } as Partial<Help>;\n}\n","import { Command } from \"commander\";\nimport { removeApiKey, getApiKey } from \"../lib/config.js\";\nimport * as ui from \"../lib/ui.js\";\n\nexport const logoutCommand = new Command(\"logout\")\n .description(\"Remove stored API key\")\n .action(() => {\n if (!getApiKey()) {\n ui.info(\"Not currently authenticated.\");\n return;\n }\n removeApiKey();\n ui.success(\"Logged out. API key removed.\");\n });\n","import { Command } from \"commander\";\nimport { requireAuth, apiGet } from \"../lib/api.js\";\nimport { setUserInfo } from \"../lib/config.js\";\nimport * as ui from \"../lib/ui.js\";\nimport type { MeResponse } from \"../types/api.js\";\n\nexport const whoamiCommand = new Command(\"whoami\")\n .description(\"Show current user info\")\n // U1: JSON output\n .option(\"--json\", \"Output raw JSON\")\n .action(async (options: { json?: boolean }) => {\n requireAuth();\n\n const spin = ui.spinner(\"Fetching account info...\");\n\n try {\n const result = await apiGet<MeResponse>(\"/api/v1/me\");\n spin.stop();\n\n const d = result.data;\n\n // Cache user info for home screen greeting\n setUserInfo(d.email, d.name);\n\n // U1: JSON output\n if (options.json) {\n ui.outputJson(d);\n return;\n }\n\n // Header with email\n ui.header(d.email);\n const badge = ui.tierBadge(d.tier, d.product);\n console.log(\n ` ${badge} ${ui.c.muted(\"·\")} ${ui.c.secondary(\"Joined\")} ${ui.c.primary(ui.formatDate(d.created_at))}`\n );\n ui.spacer();\n\n // Alias usage\n ui.sectionTitle(\"Alias\");\n ui.usageRow(\"Random\", d.aliases.random.used, d.aliases.random.limit);\n ui.usageRow(\"Custom\", d.aliases.custom.used, d.aliases.custom.limit);\n ui.usageRow(\"Recipients\", d.recipients.used, d.recipients.limit);\n ui.usageRow(\"Domains\", d.domains.used, d.domains.limit);\n ui.spacer();\n\n // Drop usage\n ui.sectionTitle(\"Drop\");\n ui.usageRow(\"Active\", d.drops.count);\n ui.storageRow(\"Storage\", parseInt(d.storage.used), parseInt(d.storage.limit));\n ui.alignedKeyValue(\"Max File\", ui.formatBytes(d.limits.max_file_size), 14);\n ui.alignedKeyValue(\"Expiry\", ui.formatDays(d.limits.max_expiry_days), 14);\n ui.spacer();\n\n // API\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to fetch account info.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { dropUploadCommand } from \"./drop-upload.js\";\nimport { dropListCommand } from \"./drop-list.js\";\nimport { dropDeleteCommand } from \"./drop-delete.js\";\nimport { dropDownloadCommand } from \"./drop-download.js\";\nimport { dropToggleCommand } from \"./drop-toggle.js\";\nimport { dropInfoCommand } from \"./drop-info.js\";\nimport { dropShareCommand } from \"./drop-share.js\";\n\nexport const dropCommand = new Command(\"drop\")\n .description(\"Encrypted file drops\")\n .addCommand(dropUploadCommand)\n .addCommand(dropListCommand)\n .addCommand(dropDeleteCommand)\n .addCommand(dropDownloadCommand)\n .addCommand(dropToggleCommand)\n .addCommand(dropInfoCommand)\n .addCommand(dropShareCommand);\n","import { Command } from \"commander\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { requireAuth, apiFetch, apiRawFetch } from \"../lib/api.js\";\nimport { fetchPlanInfo, assertFeature, assertStorageLimit, warnExpiryCap } from \"../lib/limits.js\";\nimport { getBaseUrl } from \"../lib/config.js\";\nimport * as crypto from \"../lib/crypto.js\";\nimport * as ui from \"../lib/ui.js\";\nimport { lookup } from \"mime-types\";\nimport type {\n CreateDropResponse,\n AddFileResponse,\n} from \"../types/api.js\";\n\ninterface FileEntry {\n absolutePath: string;\n relativeName: string;\n size: number;\n tmpFile?: boolean; // true if this is a temp file to clean up\n}\n\nfunction collectFiles(inputPath: string): FileEntry[] {\n const stat = fs.statSync(inputPath);\n\n if (stat.isFile()) {\n return [\n {\n absolutePath: inputPath,\n relativeName: path.basename(inputPath),\n size: stat.size,\n },\n ];\n }\n\n if (stat.isDirectory()) {\n const entries: FileEntry[] = [];\n const walk = (dir: string, prefix: string) => {\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const fullPath = path.join(dir, entry.name);\n const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;\n if (entry.isFile()) {\n entries.push({\n absolutePath: fullPath,\n relativeName: relPath,\n size: fs.statSync(fullPath).size,\n });\n } else if (entry.isDirectory()) {\n walk(fullPath, relPath);\n }\n }\n };\n walk(inputPath, \"\");\n return entries;\n }\n\n throw new Error(`${inputPath} is not a file or directory`);\n}\n\n// S2: Simple password entropy estimate\nfunction checkPasswordStrength(password: string): void {\n if (password.length < 12) {\n ui.warn(`Password is short (${password.length} chars). At least 12 characters recommended.`);\n return;\n }\n const uniqueChars = new Set(password).size;\n const entropy = password.length * Math.log2(Math.max(uniqueChars, 2));\n if (entropy < 40) {\n ui.warn(\"Password may be weak (low entropy). Consider a longer, more varied passphrase.\");\n }\n}\n\nexport const dropUploadCommand = new Command(\"upload\")\n .argument(\"[path]\", \"File or folder to upload (omit to read from stdin)\")\n .description(\"Create an encrypted drop\")\n .option(\"-t, --title <title>\", \"Drop title\")\n .option(\"-m, --message <message>\", \"Drop message\")\n .option(\"-e, --expiry <days>\", \"Expiry in days\", parseInt)\n .option(\"-n, --max-downloads <n>\", \"Max download count\", parseInt)\n .option(\"-p, --password <password>\", \"Password-protect the drop\")\n .option(\"--name <filename>\", \"Filename when reading from stdin\")\n .option(\"--hide-branding\", \"Hide anon.li branding on download page\")\n .option(\"--notify\", \"Send email notification when files are downloaded\")\n .action(async (inputPath: string | undefined, options: {\n title?: string;\n message?: string;\n expiry?: number;\n maxDownloads?: number;\n password?: string;\n name?: string;\n hideBranding?: boolean;\n notify?: boolean;\n }) => {\n requireAuth();\n\n let files: FileEntry[];\n let stdinTmpFile: string | undefined;\n\n // F4: Stdin upload support\n if (!inputPath) {\n if (process.stdin.isTTY) {\n ui.error(\"No path provided. Provide a file/folder path, or pipe data via stdin.\");\n process.exit(1);\n }\n if (!options.name) {\n ui.error(\"--name <filename> is required when uploading from stdin.\");\n process.exit(1);\n }\n\n const spin = ui.spinner(\"Reading from stdin...\");\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n const data = Buffer.concat(chunks);\n spin.stop();\n\n stdinTmpFile = path.join(os.tmpdir(), `anonli-stdin-${Date.now()}-${Math.random().toString(36).slice(2)}`);\n fs.writeFileSync(stdinTmpFile, data, { mode: 0o600 });\n files = [{\n absolutePath: stdinTmpFile,\n relativeName: options.name,\n size: data.length,\n tmpFile: true,\n }];\n } else {\n const resolved = path.resolve(inputPath);\n if (!fs.existsSync(resolved)) {\n ui.error(`Path not found: ${resolved}`);\n process.exit(1);\n }\n files = collectFiles(resolved);\n }\n\n if (files.length === 0) {\n ui.error(\"No files found.\");\n process.exit(1);\n }\n\n const totalSize = files.reduce((sum, f) => sum + f.size, 0);\n ui.info(\n `${files.length} file(s), ${ui.formatBytes(totalSize)} total`\n );\n\n // S2: Warn about weak password before expensive operations\n if (options.password) {\n checkPasswordStrength(options.password);\n }\n\n // Check plan limits before starting expensive encryption\n const limitSpin = ui.spinner(\"Checking plan limits...\");\n const plan = await fetchPlanInfo();\n limitSpin.stop();\n\n if (options.hideBranding) {\n assertFeature(plan.features, \"noBranding\", \"--hide-branding\");\n }\n if (options.notify) {\n assertFeature(plan.features, \"downloadNotifications\", \"--notify\");\n }\n if (options.password) {\n assertFeature(plan.features, \"customKey\", \"--password\");\n }\n assertStorageLimit(totalSize, plan.storage.used, plan.storage.limit);\n if (options.expiry) {\n options.expiry = warnExpiryCap(options.expiry, plan.limits.max_expiry_days);\n }\n\n try {\n // 1. Generate encryption context\n const ctx = await crypto.createEncryptionContext();\n const { key, keyString, baseIv, ivString } = ctx;\n\n // 2. Handle password protection\n let customKey = false;\n let salt: string | undefined;\n let customKeyData: string | undefined;\n let customKeyIv: string | undefined;\n\n if (options.password) {\n const protection = await crypto.encryptKeyWithPassword(\n keyString,\n options.password\n );\n customKey = true;\n salt = protection.salt;\n customKeyData = protection.encryptedKey;\n customKeyIv = protection.iv;\n }\n\n // 3. Encrypt title/message\n let encryptedTitle: string | undefined;\n let encryptedMessage: string | undefined;\n\n if (options.title) {\n encryptedTitle = await crypto.encryptFilename(\n options.title,\n key,\n baseIv\n );\n }\n if (options.message) {\n encryptedMessage = await crypto.encryptFilename(\n options.message,\n key,\n baseIv\n );\n }\n\n // 4. Create drop\n const createSpin = ui.spinner(\"Creating drop...\");\n const createRes = await apiFetch(\"/api/v1/drop\", {\n method: \"POST\",\n body: JSON.stringify({\n iv: ivString,\n fileCount: files.length,\n ...(encryptedTitle && { encryptedTitle }),\n ...(encryptedMessage && { encryptedMessage }),\n ...(options.expiry && { expiry: options.expiry }),\n ...(options.maxDownloads && { maxDownloads: options.maxDownloads }),\n ...(options.hideBranding && { hideBranding: true }),\n ...(options.notify && { notifyOnDownload: true }),\n ...(customKey && {\n customKey: true,\n salt,\n customKeyData,\n customKeyIv,\n }),\n }),\n });\n\n if (!createRes.ok) {\n const err = await createRes.json().catch(() => ({}));\n createSpin.fail(\"Failed to create drop\");\n ui.error(\n (err as { error?: { message?: string } })?.error?.message ||\n (err as { error?: string })?.error ||\n \"Unknown error\"\n );\n process.exit(1);\n }\n\n const createData = (await createRes.json()) as {\n data: CreateDropResponse;\n };\n const { drop_id: dropId, session_token: sessionToken } =\n createData.data;\n createSpin.succeed(`Drop created: ${dropId}`);\n\n // 5. Upload each file\n const fileChunkRecords: {\n fileId: string;\n chunks: { chunkIndex: number; etag: string }[];\n }[] = [];\n\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n const { chunkSize, chunkCount } = crypto.getChunkParams(file.size);\n const encryptedSize = crypto.calculateEncryptedSize(\n file.size,\n chunkSize\n );\n\n // Encrypt filename\n const encryptedName = await crypto.encryptFilename(\n file.relativeName,\n key,\n baseIv\n );\n\n // Add file to drop\n const addRes = await apiFetch(`/api/v1/drop/${dropId}/file`, {\n method: \"POST\",\n body: JSON.stringify({\n size: encryptedSize,\n encryptedName,\n iv: ivString,\n mimeType: lookup(file.absolutePath) || \"application/octet-stream\",\n chunkCount,\n chunkSize,\n ...(sessionToken && { sessionToken }),\n }),\n });\n\n if (!addRes.ok) {\n const err = await addRes.json().catch(() => ({}));\n ui.error(\n `Failed to add file ${file.relativeName}: ${\n (err as { error?: string })?.error || \"Unknown error\"\n }`\n );\n process.exit(1);\n }\n\n const addData = (await addRes.json()) as AddFileResponse;\n const { fileId, uploadUrls } = addData;\n\n // U5: Progress bar label shows file name and chunk progress\n const bar = ui.progressBar(\n chunkCount,\n `${files.length > 1 ? `[${i + 1}/${files.length}] ` : \"\"}${file.relativeName}`\n );\n const chunks: { chunkIndex: number; etag: string }[] = [];\n\n const concurrency = crypto.getConcurrency(file.size);\n const fd = fs.openSync(file.absolutePath, \"r\");\n\n try {\n let nextChunk = 0;\n\n async function processChunk(\n chunkIndex: number\n ): Promise<void> {\n const start = chunkIndex * chunkSize;\n const end = Math.min(start + chunkSize, file.size);\n const length = end - start;\n\n const buffer = Buffer.alloc(length);\n fs.readSync(fd, buffer, 0, length, start);\n\n const encrypted = await crypto.encryptChunk(\n buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength\n ),\n key,\n baseIv,\n chunkIndex\n );\n\n const presignedUrl = uploadUrls[String(chunkIndex + 1)];\n let url = presignedUrl;\n const headers: Record<string, string> = {};\n\n if (url.includes(\"/relay/\") && url.includes(\"?\")) {\n const splitIndex = url.indexOf(\"?\");\n const baseUrl = url.slice(0, splitIndex);\n const query = url.slice(splitIndex + 1);\n url = baseUrl;\n headers[\"X-Relay-Query\"] = query;\n }\n\n const uploadRes = await apiRawFetch(url, {\n method: \"PUT\",\n headers,\n body: new Uint8Array(encrypted),\n });\n\n if (!uploadRes.ok) {\n throw new Error(\n `Failed to upload chunk ${chunkIndex} of ${file.relativeName}`\n );\n }\n\n const etag = uploadRes.headers.get(\"ETag\") || \"\";\n chunks.push({ chunkIndex, etag });\n bar.increment();\n }\n\n let firstError: Error | null = null;\n const running: Promise<void>[] = [];\n while (nextChunk < chunkCount && !firstError) {\n while (running.length < concurrency && nextChunk < chunkCount && !firstError) {\n const idx = nextChunk++;\n const p = processChunk(idx)\n .then(() => {\n running.splice(running.indexOf(p), 1);\n })\n .catch((err) => {\n firstError = err instanceof Error ? err : new Error(String(err));\n running.splice(running.indexOf(p), 1);\n });\n running.push(p);\n }\n if (running.length > 0) {\n await Promise.race(running);\n }\n }\n if (running.length > 0) {\n await Promise.allSettled(running);\n }\n if (firstError) {\n throw firstError;\n }\n } finally {\n fs.closeSync(fd);\n }\n bar.stop();\n\n chunks.sort((a, b) => a.chunkIndex - b.chunkIndex);\n fileChunkRecords.push({ fileId, chunks });\n }\n\n // 6. Finalize drop\n const finishSpin = ui.spinner(\"Finalizing drop...\");\n const finishRes = await apiFetch(\n `/api/v1/drop/${dropId}?action=finish`,\n {\n method: \"PATCH\",\n body: JSON.stringify({\n files: fileChunkRecords,\n ...(sessionToken && { sessionToken }),\n }),\n }\n );\n\n if (!finishRes.ok) {\n const err = await finishRes.json().catch(() => ({}));\n finishSpin.fail(\"Failed to finalize drop\");\n ui.error(\n (err as { error?: string })?.error || \"Unknown error\"\n );\n process.exit(1);\n }\n\n finishSpin.stop();\n\n // 7. Build share URL (U6: clickable terminal link)\n const baseUrl = getBaseUrl();\n const shareUrl = customKey\n ? `${baseUrl}/d/${dropId}`\n : `${baseUrl}/d/${dropId}#${keyString}`;\n\n const boxLines = [\n `${ui.c.secondary(\"URL:\")} ${ui.link(shareUrl)}`,\n `${ui.c.secondary(\"Files:\")} ${ui.c.primary(String(files.length))}`,\n `${ui.c.secondary(\"Size:\")} ${ui.c.primary(ui.formatBytes(totalSize))}`,\n ];\n if (options.expiry) {\n boxLines.push(`${ui.c.secondary(\"Expiry:\")} ${ui.c.primary(String(options.expiry))} days`);\n }\n if (options.maxDownloads) {\n boxLines.push(`${ui.c.secondary(\"Max downloads:\")} ${ui.c.primary(String(options.maxDownloads))}`);\n }\n if (options.hideBranding) {\n boxLines.push(`${ui.c.secondary(\"Branding:\")} ${ui.c.muted(\"hidden\")}`);\n }\n if (options.notify) {\n boxLines.push(`${ui.c.secondary(\"Notifications:\")} ${ui.c.accent(\"enabled\")}`);\n }\n\n ui.successBox(\"Drop Created\", boxLines.join(\"\\n\"));\n ui.spacer();\n if (!customKey) {\n ui.warn(\n \"Save this URL — the key after # is required to decrypt.\"\n );\n } else {\n ui.info(\"Password-protected. Share the URL and password separately.\");\n }\n } catch (err) {\n ui.error(err instanceof Error ? err.message : \"Upload failed\");\n process.exit(1);\n } finally {\n // F4: Clean up stdin temp file\n if (stdinTmpFile) {\n try { fs.unlinkSync(stdinTmpFile); } catch { /* ignore */ }\n }\n }\n });\n","import { apiGet } from \"./api.js\";\nimport { PlanLimitError } from \"./errors.js\";\nimport * as ui from \"./ui.js\";\nimport type { MeResponse } from \"../types/api.js\";\n\nconst FEATURE_MAP: Record<string, { label: string; tier: string }> = {\n noBranding: { label: \"Hide branding\", tier: \"Pro\" },\n downloadNotifications: { label: \"Download notifications\", tier: \"Pro\" },\n customKey: { label: \"Password protection\", tier: \"Plus\" },\n};\n\nexport async function fetchPlanInfo(): Promise<MeResponse> {\n const { data } = await apiGet<MeResponse>(\"/api/v1/me\");\n return data;\n}\n\nexport function assertFeature(\n features: MeResponse[\"features\"],\n featureKey: keyof MeResponse[\"features\"],\n flagName: string\n): void {\n if (features[featureKey]) return;\n\n const info = FEATURE_MAP[featureKey];\n const label = info?.label ?? featureKey;\n const tier = info?.tier ?? \"a paid\";\n\n throw new PlanLimitError(\n `${label} (${flagName}) requires a ${tier} plan.`,\n `Upgrade with: anonli subscribe`\n );\n}\n\nexport function assertCountLimit(\n resourceName: string,\n used: number,\n limit: number\n): void {\n if (limit === 0) {\n throw new PlanLimitError(\n `${capitalize(resourceName)} is not available on your plan.`,\n `Upgrade with: anonli subscribe`\n );\n }\n if (used >= limit) {\n throw new PlanLimitError(\n `${capitalize(resourceName)} limit reached (${used}/${limit}).`,\n `Upgrade with: anonli subscribe`\n );\n }\n}\n\nexport function assertStorageLimit(\n totalUploadSize: number,\n storageUsed: string,\n storageLimit: string\n): void {\n const used = BigInt(storageUsed);\n const limit = BigInt(storageLimit);\n const upload = BigInt(totalUploadSize);\n\n if (used + upload > limit) {\n const available = limit > used ? Number(limit - used) : 0;\n throw new PlanLimitError(\n `Upload size (${ui.formatBytes(totalUploadSize)}) exceeds available storage (${ui.formatBytes(available)} of ${ui.formatBytes(Number(limit))} remaining).`,\n `Upgrade with: anonli subscribe`\n );\n }\n}\n\nexport function warnExpiryCap(\n requestedDays: number,\n maxDays: number\n): number {\n if (requestedDays > maxDays) {\n ui.warn(\n `Expiry capped to ${maxDays} days on your plan (requested ${requestedDays}).`\n );\n return maxDays;\n }\n return requestedDays;\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n","/**\n * Exact port of lib/crypto.client.ts for Node.js.\n * Uses crypto.subtle (Web Crypto API available in Node 18+).\n * Cross-compatible: CLI-encrypted files decrypt in the web client and vice versa.\n */\n\nimport { webcrypto } from \"node:crypto\";\nimport {\n MAX_CHUNKS_PER_FILE,\n MIN_CHUNK_SIZE,\n ARGON2_MEMORY,\n ARGON2_TIME,\n ARGON2_PARALLELISM,\n ARGON2_HASH_LENGTH,\n AUTH_TAG_SIZE,\n IV_LENGTH,\n SALT_LENGTH,\n FILE_SIZE_THRESHOLD_1GB,\n} from \"./constants.js\";\nimport { argon2id } from \"hash-wasm\";\n\ntype WebCryptoKey = webcrypto.CryptoKey;\n\nconst subtle = webcrypto.subtle;\nconst getRandomValues = webcrypto.getRandomValues.bind(webcrypto);\n\nconst ALGORITHM = { name: \"AES-GCM\", length: 256 };\n\nexport interface EncryptionContext {\n key: WebCryptoKey;\n keyString: string;\n baseIv: Uint8Array;\n ivString: string;\n}\n\n// ── Key management ──────────────────────────────────────────────────\n\nexport async function generateKey(): Promise<string> {\n const key = await subtle.generateKey(ALGORITHM, true, [\n \"encrypt\",\n \"decrypt\",\n ]);\n const exported = await subtle.exportKey(\"raw\", key);\n return arrayBufferToBase64Url(exported);\n}\n\nexport async function importKey(keyString: string): Promise<WebCryptoKey> {\n const keyData = base64UrlToArrayBuffer(keyString);\n return subtle.importKey(\"raw\", keyData, ALGORITHM, true, [\n \"encrypt\",\n \"decrypt\",\n ]);\n}\n\nexport async function createEncryptionContext(): Promise<EncryptionContext> {\n const keyString = await generateKey();\n const key = await importKey(keyString);\n const ivString = generateBaseIv();\n const baseIv = new Uint8Array(base64UrlToArrayBuffer(ivString));\n return { key, keyString, baseIv, ivString };\n}\n\nexport async function restoreEncryptionContext(\n keyString: string,\n ivString: string\n): Promise<EncryptionContext> {\n const key = await importKey(keyString);\n const baseIv = new Uint8Array(base64UrlToArrayBuffer(ivString));\n return { key, keyString, baseIv, ivString };\n}\n\n// ── Chunk encryption / decryption ───────────────────────────────────\n\nexport async function encryptChunk(\n chunk: ArrayBuffer,\n key: WebCryptoKey,\n baseIv: Uint8Array,\n chunkIndex: number\n): Promise<ArrayBuffer> {\n const iv = generateChunkIv(baseIv, chunkIndex);\n return subtle.encrypt({ name: \"AES-GCM\", iv: getView(iv) }, key, chunk);\n}\n\nexport async function decryptChunk(\n encryptedChunk: ArrayBuffer,\n key: WebCryptoKey,\n baseIv: Uint8Array,\n chunkIndex: number\n): Promise<ArrayBuffer> {\n const iv = generateChunkIv(baseIv, chunkIndex);\n return subtle.decrypt(\n { name: \"AES-GCM\", iv: getView(iv) },\n key,\n encryptedChunk\n );\n}\n\n// ── Filename encryption ─────────────────────────────────────────────\n\nexport async function encryptFilename(\n filename: string,\n key: WebCryptoKey,\n iv: Uint8Array\n): Promise<string> {\n const encoder = new TextEncoder();\n const filenameBuffer = encoder.encode(filename);\n const filenameIv = generateChunkIv(iv, 0xffffffff);\n const encrypted = await subtle.encrypt(\n { name: \"AES-GCM\", iv: getView(filenameIv) },\n key,\n filenameBuffer\n );\n return arrayBufferToBase64Url(encrypted);\n}\n\nexport async function decryptFilename(\n encryptedFilename: string,\n key: WebCryptoKey,\n iv: Uint8Array\n): Promise<string> {\n const encrypted = base64UrlToArrayBuffer(encryptedFilename);\n const filenameIv = generateChunkIv(iv, 0xffffffff);\n const decrypted = await subtle.decrypt(\n { name: \"AES-GCM\", iv: getView(filenameIv) },\n key,\n encrypted\n );\n return new TextDecoder().decode(decrypted);\n}\n\n// ── Password-based key wrapping ─────────────────────────────────────\n\nexport async function encryptKeyWithPassword(\n keyString: string,\n password: string\n): Promise<{ encryptedKey: string; iv: string; salt: string }> {\n const salt = generateSalt();\n const wrappingKey = await deriveKeyFromPassword(password, salt);\n const iv = generateBaseIv();\n const ivBuffer = new Uint8Array(base64UrlToArrayBuffer(iv));\n\n const encoder = new TextEncoder();\n const keyData = encoder.encode(keyString);\n\n const encrypted = await subtle.encrypt(\n { name: \"AES-GCM\", iv: ivBuffer },\n wrappingKey,\n keyData\n );\n\n return {\n encryptedKey: arrayBufferToBase64Url(encrypted),\n iv,\n salt,\n };\n}\n\nexport async function decryptKeyWithPassword(\n encryptedKey: string,\n password: string,\n salt: string,\n iv: string\n): Promise<string> {\n const wrappingKey = await deriveKeyFromPassword(password, salt);\n const ivBuffer = new Uint8Array(base64UrlToArrayBuffer(iv));\n const encryptedData = base64UrlToArrayBuffer(encryptedKey);\n\n const decrypted = await subtle.decrypt(\n { name: \"AES-GCM\", iv: ivBuffer },\n wrappingKey,\n encryptedData\n );\n\n return new TextDecoder().decode(decrypted);\n}\n\n// ── Chunk sizing ────────────────────────────────────────────────────\n\nexport function getChunkParams(fileSize: number): {\n chunkSize: number;\n chunkCount: number;\n} {\n if (fileSize <= MIN_CHUNK_SIZE) {\n return { chunkSize: fileSize || 1, chunkCount: 1 };\n }\n\n const chunksNeeded = Math.ceil(fileSize / MIN_CHUNK_SIZE);\n\n if (chunksNeeded <= MAX_CHUNKS_PER_FILE) {\n return {\n chunkSize: Math.ceil(fileSize / chunksNeeded),\n chunkCount: chunksNeeded,\n };\n } else {\n return {\n chunkSize: Math.ceil(fileSize / MAX_CHUNKS_PER_FILE),\n chunkCount: MAX_CHUNKS_PER_FILE,\n };\n }\n}\n\nexport function calculateEncryptedSize(\n originalSize: number,\n chunkSize: number\n): number {\n const chunkCount = Math.ceil(originalSize / chunkSize);\n return originalSize + chunkCount * AUTH_TAG_SIZE;\n}\n\nexport function getConcurrency(fileSize: number): number {\n return fileSize < FILE_SIZE_THRESHOLD_1GB ? 3 : 5;\n}\n\n// ── Internal helpers ────────────────────────────────────────────────\n\nfunction generateChunkIv(baseIv: Uint8Array, chunkIndex: number): Uint8Array {\n const iv = new Uint8Array(IV_LENGTH);\n iv.set(baseIv.slice(0, 8));\n const view = new DataView(iv.buffer);\n view.setUint32(8, chunkIndex, false); // Big-endian\n return iv;\n}\n\nfunction generateBaseIv(): string {\n const iv = getRandomValues(new Uint8Array(IV_LENGTH));\n return arrayBufferToBase64Url(iv);\n}\n\nfunction generateSalt(): string {\n const salt = getRandomValues(new Uint8Array(SALT_LENGTH));\n return arrayBufferToBase64Url(salt);\n}\n\nasync function deriveKeyFromPassword(\n password: string,\n salt: string\n): Promise<WebCryptoKey> {\n const saltBytes = new Uint8Array(base64UrlToArrayBuffer(salt));\n\n const hash = await argon2id({\n password,\n salt: saltBytes,\n memorySize: ARGON2_MEMORY,\n iterations: ARGON2_TIME,\n parallelism: ARGON2_PARALLELISM,\n hashLength: ARGON2_HASH_LENGTH,\n outputType: \"binary\",\n });\n\n return subtle.importKey(\n \"raw\",\n hash,\n ALGORITHM,\n true,\n [\"encrypt\", \"decrypt\"]\n );\n}\n\nfunction getView(arr: Uint8Array | ArrayBuffer): ArrayBuffer {\n if (arr instanceof ArrayBuffer) return arr;\n return arr.buffer.slice(\n arr.byteOffset,\n arr.byteOffset + arr.byteLength\n ) as ArrayBuffer;\n}\n\n// ── Base64url encoding ──────────────────────────────────────────────\n\nexport function arrayBufferToBase64Url(\n buffer: ArrayBuffer | Uint8Array\n): string {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n return Buffer.from(bytes)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nexport function base64UrlToArrayBuffer(base64url: string): ArrayBuffer {\n let base64 = base64url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n while (base64.length % 4) {\n base64 += \"=\";\n }\n const buf = Buffer.from(base64, \"base64\");\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n}\n","import { Command } from \"commander\";\nimport { requireAuth, apiGetList } from \"../lib/api.js\";\nimport * as ui from \"../lib/ui.js\";\nimport type { DropListItem } from \"../types/api.js\";\n\nexport const dropListCommand = new Command(\"list\")\n .alias(\"ls\")\n .description(\"List your drops\")\n .option(\"--limit <n>\", \"Number of drops to fetch\", parseInt)\n .option(\"--offset <n>\", \"Offset for pagination\", parseInt)\n // F6: Filters\n .option(\"--expired\", \"Show only expired drops\")\n .option(\"--disabled\", \"Show only disabled drops\")\n .option(\"--enabled\", \"Show only enabled drops\")\n .option(\"--sort <field>\", \"Sort by: created, expiry, size, downloads\", \"created\")\n .option(\"--order <dir>\", \"Sort direction: asc, desc\", \"desc\")\n // U1: JSON output\n .option(\"--json\", \"Output raw JSON\")\n .action(async (options: {\n limit?: number;\n offset?: number;\n expired?: boolean;\n disabled?: boolean;\n enabled?: boolean;\n sort?: string;\n order?: string;\n json?: boolean;\n }) => {\n requireAuth();\n\n const spin = ui.spinner(\"Fetching drops...\");\n\n try {\n const limit = options.limit ?? 50; // B8: standardized to 50\n const offset = options.offset ?? 0;\n const result = await apiGetList<DropListItem>(\n `/api/v1/drop?limit=${limit}&offset=${offset}`\n );\n spin.stop();\n\n // U1: JSON output\n if (options.json) {\n ui.outputJson(result.data);\n return;\n }\n\n // F6: Client-side filtering\n let data = result.data;\n const now = new Date();\n\n if (options.expired) {\n data = data.filter((d) => d.expires_at && new Date(d.expires_at) < now);\n }\n if (options.disabled) {\n data = data.filter((d) => d.disabled);\n }\n if (options.enabled) {\n data = data.filter((d) => !d.disabled);\n }\n\n // F6: Client-side sorting\n if (options.sort) {\n data = [...data].sort((a, b) => {\n let cmp = 0;\n switch (options.sort) {\n case \"expiry\":\n cmp = (a.expires_at ?? \"\").localeCompare(b.expires_at ?? \"\");\n break;\n case \"size\":\n cmp = parseInt(a.totalSize || \"0\") - parseInt(b.totalSize || \"0\");\n break;\n case \"downloads\":\n cmp = a.downloads - b.downloads;\n break;\n default: // \"created\"\n cmp = a.created_at.localeCompare(b.created_at);\n }\n return options.order === \"asc\" ? cmp : -cmp;\n });\n }\n\n if (data.length === 0) {\n ui.box(\n `${ui.c.secondary(\"No drops found.\")}\\n${ui.c.muted('Create one with')} ${ui.c.accent(\"anonli drop upload <file>\")}`,\n { title: ui.c.info(\"Drops\") }\n );\n return;\n }\n\n ui.table(\n [\"ID\", \"Status\", \"Files\", \"Size\", \"Downloads\", \"Expires\", \"Created\"],\n data.map((d) => [\n d.id,\n d.disabled\n ? ui.statusBadge(\"Disabled\", \"inactive\")\n : ui.statusBadge(\"Active\", \"active\"),\n String(d.fileCount),\n ui.formatBytes(parseInt(d.totalSize || \"0\")),\n d.maxDownloads\n ? `${d.downloads}/${d.maxDownloads}`\n : String(d.downloads),\n d.expires_at\n ? ui.formatDate(d.expires_at)\n : ui.dim(\"never\"),\n ui.formatDate(d.created_at),\n ])\n );\n\n const storage = result.meta?.storage as\n | { used: string; limit: string }\n | undefined;\n if (storage) {\n console.log(\n ui.dim(\n `\\n Storage: ${ui.formatBytes(parseInt(storage.used))}/${ui.formatBytes(parseInt(storage.limit))}`\n )\n );\n }\n\n console.log(ui.dim(` ${result.total} drop(s) total${data.length < result.data.length ? `, ${data.length} shown after filter` : \"\"}`));\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to list drops.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { requireAuth, apiDelete } from \"../lib/api.js\";\nimport * as ui from \"../lib/ui.js\";\nimport { parseDropIdentifier } from \"../lib/drop-url.js\";\n\nexport const dropDeleteCommand = new Command(\"delete\")\n .alias(\"rm\")\n .description(\"Delete a drop\")\n .argument(\"<target>\", \"Drop URL or drop ID\")\n .option(\"-f, --force\", \"Skip confirmation\")\n .action(async (target: string, options: { force?: boolean }) => {\n const { dropId } = parseDropIdentifier(target);\n requireAuth();\n\n if (!options.force) {\n const confirmed = await ui.confirm(\n `Delete drop ${ui.bold(dropId)}? This cannot be undone.`\n );\n if (!confirmed) {\n ui.info(\"Cancelled.\");\n return;\n }\n }\n\n const spin = ui.spinner(\"Deleting drop...\");\n\n try {\n const result = await apiDelete(`/api/v1/drop/${dropId}`);\n spin.succeed(`Deleted drop ${dropId}`);\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to delete drop.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","export interface DropIdentifier {\n dropId: string;\n key: string | null;\n}\n\n/**\n * Parse a drop target that can be either:\n * - A full URL: https://anon.li/d/<id>#<key>\n * - A plain drop ID: abc123\n *\n * Returns the extracted drop ID and (if present) the decryption key.\n */\nexport function parseDropIdentifier(input: string): DropIdentifier {\n try {\n const parsed = new URL(input);\n const pathParts = parsed.pathname.split(\"/\").filter(Boolean);\n const dIndex = pathParts.indexOf(\"d\");\n if (dIndex === -1 || !pathParts[dIndex + 1]) {\n throw new Error(\"Invalid URL format\");\n }\n return {\n dropId: pathParts[dIndex + 1],\n key: parsed.hash.slice(1) || null,\n };\n } catch {\n // Not a valid URL — treat as a plain drop ID\n return { dropId: input, key: null };\n }\n}\n","import { Command } from \"commander\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport * as crypto from \"../lib/crypto.js\";\nimport * as ui from \"../lib/ui.js\";\nimport { AUTH_TAG_SIZE, MIN_CHUNK_SIZE } from \"../lib/constants.js\";\nimport { EXIT_NOT_FOUND } from \"../lib/errors.js\";\nimport type { DropMetadata } from \"../types/api.js\";\nimport { getBaseUrl } from \"../lib/config.js\";\nimport { parseDropIdentifier } from \"../lib/drop-url.js\";\n\nfunction sanitizeFilename(name: string): string {\n return name\n .replace(/\\.\\.[/\\\\]/g, \"\")\n .replace(/\\0/g, \"\")\n .replace(/[<>:\"/\\\\|?*\\x00-\\x1f]/g, \"_\")\n .slice(0, 200) || \"unnamed_file\";\n}\n\n// B2: resolve output path handling file collisions\nfunction resolveOutputPath(\n dir: string,\n safeName: string,\n overwrite: boolean,\n skip: boolean\n): string | null {\n const outPath = path.join(dir, safeName);\n if (!fs.existsSync(outPath)) return outPath;\n if (overwrite) return outPath;\n if (skip) {\n ui.info(`Skipping ${safeName} (already exists)`);\n return null;\n }\n // Auto-suffix: file.txt → file.1.txt, file.2.txt, …\n const ext = path.extname(safeName);\n const base = path.basename(safeName, ext);\n for (let n = 1; n <= 1000; n++) {\n const candidate = path.join(dir, `${base}.${n}${ext}`);\n if (!fs.existsSync(candidate)) return candidate;\n }\n throw new Error(`Cannot find available filename for ${safeName}`);\n}\n\nexport const dropDownloadCommand = new Command(\"download\")\n .alias(\"dl\")\n .description(\"Download and decrypt a drop\")\n .argument(\"<target>\", \"Drop URL or drop ID\")\n .option(\"-o, --output <dir>\", \"Output directory\", \".\")\n .option(\"-k, --key <key>\", \"Decryption key (required when using a drop ID)\")\n .option(\"-p, --password <password>\", \"Password for protected drops\")\n .option(\"--overwrite\", \"Overwrite existing files without prompting\")\n .option(\"--skip\", \"Skip files that already exist\")\n .action(async (target: string, options: {\n output: string;\n key?: string;\n password?: string;\n overwrite?: boolean;\n skip?: boolean;\n }) => {\n const { dropId, key: urlKey } = parseDropIdentifier(target);\n let keyString = options.key || urlKey;\n\n // Fetch drop metadata\n const spin = ui.spinner(\"Fetching drop metadata...\");\n\n try {\n const baseUrl = getBaseUrl();\n const metaRes = await fetch(`${baseUrl}/api/v1/drop/${dropId}`);\n if (!metaRes.ok) {\n spin.fail(\"Drop not found or unavailable.\");\n process.exit(metaRes.status === 404 ? EXIT_NOT_FOUND : 1);\n }\n\n const drop = (await metaRes.json()) as DropMetadata;\n spin.succeed(\n `Drop found: ${drop.files.length} file(s)`\n );\n\n // Handle custom key (password-protected)\n if (drop.customKey && !keyString) {\n if (\n !drop.customKeyData ||\n !drop.customKeyIv ||\n !drop.salt\n ) {\n ui.error(\"Drop requires a password but key data is missing.\");\n process.exit(1);\n }\n\n const password = options.password || await ui.prompt(\"Password:\", { mask: true });\n try {\n keyString = await crypto.decryptKeyWithPassword(\n drop.customKeyData,\n password,\n drop.salt,\n drop.customKeyIv\n );\n } catch {\n ui.errorBox(\"Decryption Failed\", \"Incorrect password.\");\n process.exit(1);\n }\n }\n\n if (!keyString) {\n ui.errorBox(\n \"Missing Key\",\n \"No decryption key provided. Use a URL with #<key> or pass --key <key>.\"\n );\n process.exit(1);\n return;\n }\n\n // Import key and IV\n const key = await crypto.importKey(keyString);\n const iv = new Uint8Array(\n crypto.base64UrlToArrayBuffer(drop.iv)\n );\n\n // Create output directory\n const outDir = path.resolve(options.output as string);\n fs.mkdirSync(outDir, { recursive: true });\n\n // Download and decrypt each file\n let downloadedCount = 0;\n for (const file of drop.files) {\n // B1: Warn on filename decryption failure\n let filename: string;\n try {\n filename = await crypto.decryptFilename(\n file.encryptedName,\n key,\n iv\n );\n } catch {\n ui.warn(`Could not decrypt filename for file ${file.id.slice(0, 8)} — using fallback name`);\n filename = `file_${file.id}`;\n }\n\n const encryptedSize = parseInt(file.size);\n const chunkSize = file.chunkSize || MIN_CHUNK_SIZE;\n const chunkCount = file.chunkCount || Math.ceil(encryptedSize / (chunkSize + AUTH_TAG_SIZE));\n const encryptedChunkSize = chunkSize + AUTH_TAG_SIZE;\n\n // S3: expected decrypted size\n const expectedDecryptedSize = encryptedSize - chunkCount * AUTH_TAG_SIZE;\n\n // B2: Resolve collision-safe output path\n const safeName = sanitizeFilename(filename);\n fs.mkdirSync(path.dirname(path.join(outDir, safeName)), { recursive: true });\n\n const outPath = resolveOutputPath(outDir, safeName, options.overwrite ?? false, options.skip ?? false);\n if (outPath === null) continue; // skip\n\n // F2: Check for existing partial download to resume\n const partPath = `${outPath}.anonli-dl`;\n let resumeFromChunk = 0;\n let resumeFromByte = 0;\n\n if (!options.overwrite && fs.existsSync(partPath)) {\n const partSize = fs.statSync(partPath).size;\n resumeFromChunk = Math.floor(partSize / chunkSize);\n resumeFromByte = resumeFromChunk * encryptedChunkSize;\n if (resumeFromChunk > 0) {\n ui.info(`Resuming ${filename} from chunk ${resumeFromChunk}/${chunkCount}`);\n }\n }\n\n ui.info(`Downloading ${ui.c.accent(filename)} (${ui.formatBytes(expectedDecryptedSize)})`);\n\n const downloadUrl = `${baseUrl}/api/v1/drop/${dropId}/file/${file.id}`;\n const fetchHeaders: Record<string, string> = {};\n if (resumeFromByte > 0) {\n fetchHeaders[\"Range\"] = `bytes=${resumeFromByte}-`;\n }\n\n const response = await fetch(downloadUrl, { headers: fetchHeaders });\n\n if (!response.ok && response.status !== 206) {\n ui.error(`Failed to download ${filename}: ${response.statusText}`);\n continue;\n }\n\n // If server returned 200 instead of 206, Range was ignored → restart\n if (resumeFromChunk > 0 && response.status === 200) {\n ui.warn(\"Server doesn't support resume — restarting from beginning.\");\n resumeFromChunk = 0;\n resumeFromByte = 0;\n }\n\n if (!response.body) {\n ui.error(`No response body for ${filename}`);\n continue;\n }\n\n // S4: Track bytes received vs Content-Length\n const contentLength = parseInt(response.headers.get(\"Content-Length\") || \"0\");\n let totalBytesReceived = 0;\n\n // Open part file (append if resuming, overwrite if starting fresh)\n const writeStream = fs.createWriteStream(partPath, {\n flags: resumeFromChunk > 0 ? \"a\" : \"w\",\n });\n\n const reader = response.body.getReader();\n let buffer = new Uint8Array(0);\n let chunkIndex = resumeFromChunk;\n let totalDecryptedBytes = resumeFromChunk * chunkSize; // already written\n const bar = ui.progressBar(chunkCount, filename);\n if (resumeFromChunk > 0) bar.update(resumeFromChunk);\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (value) {\n // Append to buffer\n const newBuffer = new Uint8Array(buffer.length + value.length);\n newBuffer.set(buffer);\n newBuffer.set(value, buffer.length);\n buffer = newBuffer;\n totalBytesReceived += value.length;\n }\n\n // Process complete encrypted chunks\n while (buffer.length >= encryptedChunkSize) {\n const encryptedChunk = buffer.slice(0, encryptedChunkSize);\n buffer = buffer.slice(encryptedChunkSize);\n\n const decrypted = await crypto.decryptChunk(\n encryptedChunk.buffer.slice(\n encryptedChunk.byteOffset,\n encryptedChunk.byteOffset + encryptedChunk.byteLength\n ),\n key,\n iv,\n chunkIndex\n );\n\n writeStream.write(Buffer.from(decrypted));\n totalDecryptedBytes += decrypted.byteLength;\n chunkIndex++;\n\n if (chunkCount > 0) {\n bar.update(Math.min(chunkIndex, chunkCount));\n }\n }\n\n if (done) {\n // Process remaining data (last partial chunk)\n if (buffer.length > 0) {\n const decrypted = await crypto.decryptChunk(\n buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength\n ),\n key,\n iv,\n chunkIndex\n );\n writeStream.write(Buffer.from(decrypted));\n totalDecryptedBytes += decrypted.byteLength;\n }\n break;\n }\n }\n\n await new Promise<void>((resolve, reject) => {\n writeStream.end((err: Error | null) => {\n if (err) reject(err);\n else resolve();\n });\n });\n\n bar.update(chunkCount);\n bar.stop();\n\n // S4: Warn if received bytes differ from Content-Length\n if (contentLength > 0 && totalBytesReceived !== contentLength) {\n ui.warn(\n `Content-Length mismatch for ${filename}: expected ${contentLength} bytes, received ${totalBytesReceived} bytes`\n );\n }\n\n // S3: Verify decrypted size against expected\n if (expectedDecryptedSize > 0 && totalDecryptedBytes !== expectedDecryptedSize) {\n ui.warn(\n `Size mismatch for ${filename}: expected ${ui.formatBytes(expectedDecryptedSize)}, got ${ui.formatBytes(totalDecryptedBytes)}`\n );\n }\n\n // Rename part file to final path\n fs.renameSync(partPath, outPath);\n downloadedCount++;\n } catch (err) {\n bar.stop();\n writeStream.destroy();\n // Leave part file for potential resume next time\n ui.error(`Failed to decrypt ${filename}: ${err instanceof Error ? err.message : \"Unknown error\"}`);\n }\n }\n\n ui.successBox(\n \"Download Complete\",\n `${ui.c.primary(String(downloadedCount))} ${ui.c.secondary(\"file(s) decrypted to\")} ${ui.c.accent(path.resolve(outDir))}`\n );\n } catch (err) {\n ui.error(\n err instanceof Error ? err.message : \"Download failed\"\n );\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { requireAuth, apiPatch } from \"../lib/api.js\";\nimport * as ui from \"../lib/ui.js\";\nimport { parseDropIdentifier } from \"../lib/drop-url.js\";\n\nexport const dropToggleCommand = new Command(\"toggle\")\n .description(\"Toggle a drop's enabled/disabled state\")\n .argument(\"<target>\", \"Drop URL or drop ID\")\n .action(async (target: string) => {\n const { dropId } = parseDropIdentifier(target);\n requireAuth();\n\n const spin = ui.spinner(\"Toggling drop...\");\n\n try {\n const result = await apiPatch<{ disabled: boolean }>(\n `/api/v1/drop/${dropId}?action=toggle`\n );\n\n // U8: Show new state explicitly\n if (result.data.disabled) {\n spin.succeed(`Drop ${dropId} is now ${ui.statusBadge(\"disabled\", \"inactive\")}`);\n } else {\n spin.succeed(`Drop ${dropId} is now ${ui.statusBadge(\"enabled\", \"active\")}`);\n }\n\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to toggle drop.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport * as crypto from \"../lib/crypto.js\";\nimport * as ui from \"../lib/ui.js\";\nimport { EXIT_NOT_FOUND } from \"../lib/errors.js\";\nimport type { DropMetadata } from \"../types/api.js\";\nimport { getBaseUrl } from \"../lib/config.js\";\nimport { parseDropIdentifier } from \"../lib/drop-url.js\";\n\nexport const dropInfoCommand = new Command(\"info\")\n .alias(\"get\")\n .description(\"View drop details\")\n .argument(\"<target>\", \"Drop URL or drop ID\")\n .option(\"-k, --key <key>\", \"Decryption key (to reveal filenames)\")\n .option(\"-p, --password <password>\", \"Password for protected drops\")\n // U1: JSON output\n .option(\"--json\", \"Output raw JSON\")\n .action(async (target: string, options: { key?: string; password?: string; json?: boolean }) => {\n const { dropId, key: urlKey } = parseDropIdentifier(target);\n let keyString = options.key || urlKey;\n const spin = ui.spinner(\"Fetching drop info...\");\n\n try {\n const baseUrl = getBaseUrl();\n const res = await fetch(`${baseUrl}/api/v1/drop/${dropId}`);\n\n if (!res.ok) {\n spin.fail(\"Drop not found or unavailable.\");\n process.exit(res.status === 404 ? EXIT_NOT_FOUND : 1);\n }\n\n const drop = (await res.json()) as DropMetadata;\n spin.stop();\n\n // U1: JSON output (before password prompt to keep it scriptable)\n if (options.json) {\n ui.outputJson(drop);\n return;\n }\n\n // Handle password-protected drops\n if (drop.customKey && !keyString) {\n if (drop.customKeyData && drop.customKeyIv && drop.salt) {\n const password = options.password || await ui.prompt(\"Password:\", { mask: true });\n try {\n keyString = await crypto.decryptKeyWithPassword(\n drop.customKeyData,\n password,\n drop.salt,\n drop.customKeyIv\n );\n } catch {\n ui.warn(\"Incorrect password — showing file IDs instead of names.\");\n }\n }\n }\n\n // Try to import the decryption key\n let cryptoKey: Awaited<ReturnType<typeof crypto.importKey>> | null = null;\n let iv: Uint8Array | null = null;\n if (keyString) {\n try {\n cryptoKey = await crypto.importKey(keyString);\n iv = new Uint8Array(crypto.base64UrlToArrayBuffer(drop.iv));\n } catch {\n ui.warn(\"Invalid decryption key — showing file IDs instead of names.\");\n }\n }\n\n ui.header(\"Drop Info\");\n ui.spacer();\n\n ui.keyValue(\"ID\", drop.id);\n ui.keyValue(\"Files\", String(drop.files.length));\n ui.keyValue(\"Downloads\", String(drop.downloads));\n if (drop.maxDownloads) {\n ui.keyValue(\"Max Downloads\", String(drop.maxDownloads));\n }\n if (drop.expiresAt) {\n ui.keyValue(\"Expires\", ui.formatDate(drop.expiresAt));\n }\n ui.keyValue(\"Created\", ui.formatDate(drop.createdAt));\n ui.keyValue(\"Password Protected\", drop.customKey ? \"Yes\" : \"No\");\n ui.keyValue(\"Hide Branding\", drop.hideBranding ? \"Yes\" : \"No\");\n\n if (drop.files.length > 0) {\n ui.spacer();\n ui.sectionTitle(\"Files\");\n\n const canDecrypt = cryptoKey !== null && iv !== null;\n const headers = [\"#\", canDecrypt ? \"Name\" : \"ID\", \"Size\", \"Type\"];\n const rows: string[][] = [];\n\n for (let i = 0; i < drop.files.length; i++) {\n const file = drop.files[i];\n let nameOrId: string;\n\n if (cryptoKey && iv) {\n try {\n nameOrId = await crypto.decryptFilename(file.encryptedName, cryptoKey, iv);\n } catch {\n nameOrId = file.id.slice(0, 8) + \"...\";\n }\n } else {\n nameOrId = file.id.slice(0, 8) + \"...\";\n }\n\n rows.push([\n String(i + 1),\n nameOrId,\n ui.formatBytes(parseInt(file.size)),\n file.mimeType || \"unknown\",\n ]);\n }\n\n ui.table(headers, rows);\n }\n\n ui.spacer();\n ui.info(`View: ${ui.link(`${baseUrl}/d/${dropId}`)}`);\n } catch (err) {\n spin.fail(\"Failed to fetch drop info.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport * as ui from \"../lib/ui.js\";\nimport { getBaseUrl } from \"../lib/config.js\";\n\nexport const dropShareCommand = new Command(\"share\")\n .description(\"Reconstruct the share URL for a drop (requires the original key)\")\n .argument(\"<id>\", \"Drop ID\")\n .option(\"-k, --key <key>\", \"Decryption key (the part after # in the original URL)\")\n .action((id: string, options: { key?: string }) => {\n const baseUrl = getBaseUrl();\n\n if (!options.key) {\n ui.errorBox(\n \"Key Required\",\n \"The decryption key is required to reconstruct the share URL.\",\n \"Use: anonli drop share <id> --key <key>\"\n );\n process.exit(1);\n }\n\n const shareUrl = `${baseUrl}/d/${id}#${options.key}`;\n\n ui.successBox(\n \"Share URL\",\n `${ui.c.secondary(\"URL:\")} ${ui.link(shareUrl)}`\n );\n // Also print plain URL to stdout for easy piping\n console.log(shareUrl);\n });\n","import { Command } from \"commander\";\nimport { aliasNewCommand } from \"./alias-new.js\";\nimport { aliasListCommand } from \"./alias-list.js\";\nimport { aliasDeleteCommand } from \"./alias-delete.js\";\nimport { aliasToggleCommand } from \"./alias-toggle.js\";\nimport { aliasUpdateCommand } from \"./alias-update.js\";\nimport { aliasStatsCommand } from \"./alias-stats.js\";\n\nexport const aliasCommand = new Command(\"alias\")\n .description(\"Manage email aliases\")\n .addCommand(aliasNewCommand)\n .addCommand(aliasListCommand)\n .addCommand(aliasDeleteCommand)\n .addCommand(aliasToggleCommand)\n .addCommand(aliasUpdateCommand)\n .addCommand(aliasStatsCommand);\n","import { Command } from \"commander\";\nimport { requireAuth, apiPost } from \"../lib/api.js\";\nimport { fetchPlanInfo, assertCountLimit } from \"../lib/limits.js\";\nimport * as ui from \"../lib/ui.js\";\nimport type { AliasItem } from \"../types/api.js\";\n\n// B5: Validate custom alias local part\nconst ALIAS_LOCAL_PART_RE = /^[a-z0-9][a-z0-9._+\\-]{0,61}[a-z0-9]$|^[a-z0-9]$/i;\n\nfunction validateLocalPart(localPart: string): void {\n if (!ALIAS_LOCAL_PART_RE.test(localPart)) {\n ui.error(\n `Invalid alias local part: \"${localPart}\". ` +\n \"Must start and end with a letter or digit, and contain only letters, digits, dots, underscores, plus, or hyphens (max 63 chars).\"\n );\n process.exit(1);\n }\n}\n\nexport const aliasNewCommand = new Command(\"new\")\n .alias(\"create\")\n .description(\"Create a new alias (default: random)\")\n .option(\"-r, --random\", \"Generate random alias (default)\")\n .option(\"-c, --custom <name>\", \"Custom local part\")\n .option(\"-d, --domain <domain>\", \"Domain (default: anon.li)\")\n .option(\"-l, --label <text>\", \"Description/label for the alias\")\n .option(\"--recipient <email>\", \"Recipient email to forward to\")\n .action(async (options) => {\n requireAuth();\n\n const domain = (options.domain as string) || \"anon.li\";\n const isCustom = !!options.custom;\n\n // B5: Validate custom alias format before API call\n if (isCustom) {\n validateLocalPart(options.custom as string);\n }\n\n // Check plan limits before creating\n const limitSpin = ui.spinner(\"Checking plan limits...\");\n const plan = await fetchPlanInfo();\n limitSpin.stop();\n\n if (isCustom) {\n assertCountLimit(\"custom alias\", plan.aliases.custom.used, plan.aliases.custom.limit);\n } else {\n assertCountLimit(\"random alias\", plan.aliases.random.used, plan.aliases.random.limit);\n }\n\n const spin = ui.spinner(\"Creating alias...\");\n\n try {\n let result;\n\n const body: Record<string, unknown> = {\n domain,\n ...(options.label && { description: options.label }),\n ...(options.recipient && { recipient_email: options.recipient }),\n };\n\n if (isCustom) {\n result = await apiPost<AliasItem>(\"/api/v1/alias\", {\n ...body,\n format: \"custom\",\n local_part: options.custom,\n });\n } else {\n result = await apiPost<AliasItem>(\"/api/v1/alias?generate=true\", body);\n }\n\n spin.succeed(`Created: ${ui.c.accent(result.data.email)}`);\n\n // U9: Show forwarding path in success output\n if (options.recipient) {\n ui.info(`Forwards to: ${ui.c.primary(options.recipient as string)}`);\n }\n if (result.data.description) {\n ui.info(`Label: ${result.data.description}`);\n }\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to create alias.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { requireAuth, apiGetList } from \"../lib/api.js\";\nimport * as ui from \"../lib/ui.js\";\nimport type { AliasItem } from \"../types/api.js\";\n\nexport const aliasListCommand = new Command(\"list\")\n .alias(\"ls\")\n .description(\"List all aliases\")\n .option(\"--limit <n>\", \"Number of aliases to fetch\", parseInt)\n .option(\"--offset <n>\", \"Offset for pagination\", parseInt)\n // F6: Filters\n .option(\"--active\", \"Show only active aliases\")\n .option(\"--inactive\", \"Show only inactive aliases\")\n .option(\"--search <term>\", \"Filter by email address\")\n // U1: JSON output\n .option(\"--json\", \"Output raw JSON\")\n .action(async (options: {\n limit?: number;\n offset?: number;\n active?: boolean;\n inactive?: boolean;\n search?: string;\n json?: boolean;\n }) => {\n requireAuth();\n\n const spin = ui.spinner(\"Fetching aliases...\");\n\n try {\n const limit = options.limit ?? 50; // B8: standardized to 50\n const offset = options.offset ?? 0;\n const result = await apiGetList<AliasItem>(`/api/v1/alias?limit=${limit}&offset=${offset}`);\n spin.stop();\n\n // U1: JSON output\n if (options.json) {\n ui.outputJson(result.data);\n return;\n }\n\n // F6: Client-side filtering\n let data = result.data;\n\n if (options.active) {\n data = data.filter((a) => a.active);\n }\n if (options.inactive) {\n data = data.filter((a) => !a.active);\n }\n if (options.search) {\n const term = options.search.toLowerCase();\n data = data.filter((a) => a.email.toLowerCase().includes(term));\n }\n\n if (data.length === 0) {\n ui.box(\n `${ui.c.secondary(\"No aliases found.\")}\\n${ui.c.muted('Create one with')} ${ui.c.accent(\"anonli alias new\")}`,\n { title: ui.c.info(\"Aliases\") }\n );\n return;\n }\n\n ui.table(\n [\"Email\", \"ID\", \"Status\", \"Created\"],\n data.map((a) => [\n a.email,\n a.id.slice(0, 8) + \"...\",\n a.active\n ? ui.statusBadge(\"Active\", \"active\")\n : ui.statusBadge(\"Inactive\", \"inactive\"),\n ui.formatDate(a.created_at),\n ])\n );\n\n console.log(ui.dim(\n `\\n ${result.total} alias(es) total${data.length < result.data.length ? `, ${data.length} shown after filter` : \"\"}`\n ));\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to list aliases.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { requireAuth, apiDelete } from \"../lib/api.js\";\nimport * as ui from \"../lib/ui.js\";\n\nexport const aliasDeleteCommand = new Command(\"delete\")\n .alias(\"rm\")\n .description(\"Delete an alias\")\n .argument(\"<id>\", \"Alias ID or email\")\n .option(\"-f, --force\", \"Skip confirmation\")\n .action(async (id: string, options: { force?: boolean }) => {\n requireAuth();\n\n if (!options.force) {\n const confirmed = await ui.confirm(\n `Delete alias ${ui.bold(id)}?`\n );\n if (!confirmed) {\n ui.info(\"Cancelled.\");\n return;\n }\n }\n\n const spin = ui.spinner(\"Deleting alias...\");\n\n try {\n const result = await apiDelete(`/api/v1/alias/${encodeURIComponent(id)}`);\n spin.succeed(`Deleted alias ${id}`);\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to delete alias.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { requireAuth, apiGet, apiPatch } from \"../lib/api.js\";\nimport * as ui from \"../lib/ui.js\";\n\ninterface AliasData {\n id: string;\n email: string;\n active: boolean;\n}\n\nexport const aliasToggleCommand = new Command(\"toggle\")\n .description(\"Toggle alias active/inactive\")\n .argument(\"<id>\", \"Alias ID or email\")\n .action(async (id: string) => {\n requireAuth();\n\n const spin = ui.spinner(\"Toggling alias...\");\n\n try {\n // Fetch current state first — the API requires an explicit {active} value\n const current = await apiGet<AliasData>(\n `/api/v1/alias/${encodeURIComponent(id)}`\n );\n\n const result = await apiPatch<AliasData>(\n `/api/v1/alias/${encodeURIComponent(id)}`,\n { active: !current.data.active }\n );\n const badge = result.data.active\n ? ui.statusBadge(\"Active\", \"active\")\n : ui.statusBadge(\"Inactive\", \"inactive\");\n spin.succeed(`Alias ${id} is now ${badge}`);\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to toggle alias.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { requireAuth, apiPatch } from \"../lib/api.js\";\nimport * as ui from \"../lib/ui.js\";\nimport type { AliasItem } from \"../types/api.js\";\n\nexport const aliasUpdateCommand = new Command(\"update\")\n .alias(\"edit\")\n .description(\"Update an alias\")\n .argument(\"<id>\", \"Alias ID or email\")\n .option(\"--enable\", \"Enable the alias\")\n .option(\"--disable\", \"Disable the alias\")\n .option(\"-l, --label <text>\", \"Update description/label\")\n .action(async (aliasId: string, options: { enable?: boolean; disable?: boolean; label?: string }) => {\n requireAuth();\n\n if (!options.enable && !options.disable && !options.label) {\n ui.error(\"Provide at least one option: --enable, --disable, or --label\");\n process.exit(1);\n }\n\n if (options.enable && options.disable) {\n ui.error(\"Cannot use both --enable and --disable\");\n process.exit(1);\n }\n\n const spin = ui.spinner(\"Updating alias...\");\n\n try {\n const body: Record<string, unknown> = {};\n\n if (options.enable) {\n body.active = true;\n } else if (options.disable) {\n body.active = false;\n }\n\n if (options.label !== undefined) {\n body.description = options.label;\n }\n\n const result = await apiPatch<AliasItem>(\n `/api/v1/alias/${encodeURIComponent(aliasId)}`,\n body\n );\n spin.stop();\n\n const status = result.data.active\n ? ui.statusBadge(\"Active\", \"active\")\n : ui.statusBadge(\"Inactive\", \"inactive\");\n\n ui.successBox(\n \"Alias Updated\",\n `${ui.c.accent(result.data.email)} is now ${status}`\n );\n\n if (result.data.description) {\n ui.info(`Label: ${result.data.description}`);\n }\n\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to update alias.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { requireAuth, apiGet, apiGetList } from \"../lib/api.js\";\nimport * as ui from \"../lib/ui.js\";\nimport type { AliasItem } from \"../types/api.js\";\n\ninterface AliasWithStats extends AliasItem {\n forwarded?: number;\n blocked?: number;\n last_seen?: string | null;\n}\n\nexport const aliasStatsCommand = new Command(\"stats\")\n .description(\"Show forwarding statistics for an alias\")\n .argument(\"[alias-id]\", \"Alias ID (omit to show summary across all aliases)\")\n .option(\"--all\", \"Show summary across all aliases\")\n // U1: JSON output\n .option(\"--json\", \"Output raw JSON\")\n .action(async (aliasId: string | undefined, options: { all?: boolean; json?: boolean }) => {\n requireAuth();\n\n if (aliasId && !options.all) {\n // Single alias stats\n const spin = ui.spinner(\"Fetching alias stats...\");\n\n try {\n const result = await apiGet<AliasWithStats>(\n `/api/v1/alias/${encodeURIComponent(aliasId)}`\n );\n spin.stop();\n\n const a = result.data;\n\n if (options.json) {\n ui.outputJson(a);\n return;\n }\n\n ui.header(`Alias: ${a.email}`);\n ui.spacer();\n ui.keyValue(\"ID\", a.id);\n ui.keyValue(\"Status\", a.active ? \"Active\" : \"Inactive\");\n ui.keyValue(\"Forwarded\", String(a.forwarded ?? 0));\n ui.keyValue(\"Blocked\", String(a.blocked ?? 0));\n ui.keyValue(\"Last Seen\", a.last_seen ? ui.formatDate(a.last_seen) : \"Never\");\n ui.keyValue(\"Created\", ui.formatDate(a.created_at));\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to fetch alias stats.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n } else {\n // Summary across all aliases\n const spin = ui.spinner(\"Fetching all aliases...\");\n\n try {\n const result = await apiGetList<AliasWithStats>(\"/api/v1/alias?limit=100\");\n spin.stop();\n\n const data = result.data;\n\n if (options.json) {\n const summary = {\n total: data.length,\n active: data.filter((a) => a.active).length,\n totalForwarded: data.reduce((s, a) => s + (a.forwarded ?? 0), 0),\n totalBlocked: data.reduce((s, a) => s + (a.blocked ?? 0), 0),\n aliases: data.map((a) => ({\n id: a.id,\n email: a.email,\n forwarded: a.forwarded ?? 0,\n blocked: a.blocked ?? 0,\n last_seen: a.last_seen ?? null,\n })),\n };\n ui.outputJson(summary);\n return;\n }\n\n const totalForwarded = data.reduce((s, a) => s + (a.forwarded ?? 0), 0);\n const totalBlocked = data.reduce((s, a) => s + (a.blocked ?? 0), 0);\n\n ui.header(\"Alias Statistics Summary\");\n ui.spacer();\n ui.keyValue(\"Total Aliases\", String(data.length));\n ui.keyValue(\"Active\", String(data.filter((a) => a.active).length));\n ui.keyValue(\"Total Forwarded\", String(totalForwarded));\n ui.keyValue(\"Total Blocked\", String(totalBlocked));\n ui.spacer();\n\n if (data.length > 0) {\n ui.sectionTitle(\"Per-Alias Breakdown\");\n ui.table(\n [\"Email\", \"Forwarded\", \"Blocked\", \"Last Seen\"],\n data.map((a) => [\n a.email,\n String(a.forwarded ?? 0),\n String(a.blocked ?? 0),\n a.last_seen ? ui.formatDate(a.last_seen) : ui.dim(\"never\"),\n ])\n );\n }\n\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to fetch alias stats.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n }\n });\n","import { Command } from \"commander\";\nimport { requireAuth, apiGetList, apiGet, apiPost, apiDelete, apiPatch } from \"../lib/api.js\";\nimport { fetchPlanInfo, assertCountLimit } from \"../lib/limits.js\";\nimport * as ui from \"../lib/ui.js\";\nimport type { RecipientItem } from \"../types/api.js\";\n\nexport const recipientCommand = new Command(\"recipient\")\n .alias(\"recipients\")\n .description(\"Manage email recipients\");\n\n// List recipients\nrecipientCommand\n .command(\"list\")\n .alias(\"ls\")\n .description(\"List all recipients\")\n // U1: JSON output\n .option(\"--json\", \"Output raw JSON\")\n .action(async (options: { json?: boolean }) => {\n requireAuth();\n const spin = ui.spinner(\"Fetching recipients...\");\n\n try {\n const result = await apiGetList<RecipientItem>(\"/api/v1/recipient\");\n spin.stop();\n\n // U1: JSON output\n if (options.json) {\n ui.outputJson(result.data);\n return;\n }\n\n if (result.data.length === 0) {\n ui.box(\n `${ui.c.secondary(\"No recipients yet.\")}\\n${ui.c.muted(\"Add one with\")} ${ui.c.accent(\"anonli recipient add <email>\")}`,\n { title: ui.c.info(\"Recipients\") }\n );\n return;\n }\n\n ui.table(\n [\"Email\", \"Status\", \"Default\", \"PGP\", \"Aliases\", \"Created\"],\n result.data.map((r) => [\n r.email,\n r.verified ? ui.statusBadge(\"verified\", \"active\") : ui.statusBadge(\"pending\", \"inactive\"),\n r.is_default ? ui.c.accent(\"✓\") : \"\",\n r.pgp_fingerprint ? ui.c.accent(\"✓\") : \"\",\n String(r.alias_count || 0),\n ui.formatDate(r.created_at),\n ])\n );\n\n console.log(ui.dim(` ${result.total} recipient(s) total`));\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to list recipients.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\n// Add recipient\nrecipientCommand\n .command(\"add <email>\")\n .description(\"Add a new recipient\")\n .action(async (email: string) => {\n requireAuth();\n\n // Check plan limits before adding\n const limitSpin = ui.spinner(\"Checking plan limits...\");\n const plan = await fetchPlanInfo();\n limitSpin.stop();\n assertCountLimit(\"recipient\", plan.recipients.used, plan.recipients.limit);\n\n const spin = ui.spinner(\"Adding recipient...\");\n\n try {\n const result = await apiPost<RecipientItem>(\"/api/v1/recipient\", { email });\n spin.succeed(`Added: ${ui.c.accent(result.data.email)}`);\n ui.info(\"Verification email sent. Check your inbox.\");\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to add recipient.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\n// Delete recipient\nrecipientCommand\n .command(\"delete <id>\")\n .alias(\"rm\")\n .description(\"Delete a recipient\")\n .option(\"-f, --force\", \"Skip confirmation\")\n .action(async (id: string, options) => {\n requireAuth();\n\n if (!options.force) {\n const confirmed = await ui.confirm(`Delete recipient ${id}?`);\n if (!confirmed) {\n ui.info(\"Cancelled.\");\n return;\n }\n }\n\n const spin = ui.spinner(\"Deleting recipient...\");\n\n try {\n const result = await apiDelete(`/api/v1/recipient/${encodeURIComponent(id)}`);\n spin.succeed(\"Recipient deleted.\");\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to delete recipient.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\n// Set default recipient\nrecipientCommand\n .command(\"default <id>\")\n .description(\"Set a recipient as default\")\n .action(async (id: string) => {\n requireAuth();\n const spin = ui.spinner(\"Setting default...\");\n\n try {\n const result = await apiPatch<RecipientItem>(\n `/api/v1/recipient/${encodeURIComponent(id)}`,\n { is_default: true }\n );\n spin.succeed(`${ui.c.accent(result.data.email)} is now your default recipient.`);\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to set default.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\n// Resend verification\nrecipientCommand\n .command(\"verify <id>\")\n .description(\"Resend verification email\")\n .action(async (id: string) => {\n requireAuth();\n const spin = ui.spinner(\"Sending verification email...\");\n\n try {\n const result = await apiPost(`/api/v1/recipient/${encodeURIComponent(id)}/verify`);\n spin.succeed(\"Verification email sent.\");\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to send verification.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\n// PGP subcommands\nconst pgpCommand = recipientCommand\n .command(\"pgp\")\n .description(\"Manage PGP keys for recipients\");\n\npgpCommand\n .command(\"set <id>\")\n .description(\"Set PGP public key for a recipient\")\n .option(\"-k, --key <file>\", \"Path to PGP public key file\")\n .option(\"-n, --name <name>\", \"Name/label for the key\")\n .option(\"-f, --force\", \"Skip confirmation when replacing existing key\")\n .action(async (id: string, options) => {\n requireAuth();\n\n if (!options.key) {\n ui.error(\"--key <file> is required\");\n process.exit(1);\n }\n\n const fs = await import(\"node:fs\");\n const path = await import(\"node:path\");\n\n const keyPath = path.resolve(options.key);\n if (!fs.existsSync(keyPath)) {\n ui.error(`File not found: ${keyPath}`);\n process.exit(1);\n }\n\n // B7: Reject oversized files (max 20 KB)\n const keyFileStat = fs.statSync(keyPath);\n if (keyFileStat.size > 20 * 1024) {\n ui.error(`PGP key file is too large (${ui.formatBytes(keyFileStat.size)}). Maximum allowed size is 20 KB.`);\n process.exit(1);\n }\n\n const publicKey = fs.readFileSync(keyPath, \"utf-8\");\n\n // U7: Confirm before replacing existing PGP key (check recipient first)\n if (!options.force) {\n try {\n const existing = await apiGet<{ pgp_fingerprint: string | null }>(`/api/v1/recipient/${encodeURIComponent(id)}`);\n if (existing.data.pgp_fingerprint) {\n const confirmed = await ui.confirm(\n `Recipient already has a PGP key (${existing.data.pgp_fingerprint.slice(0, 16)}...). Replace it?`\n );\n if (!confirmed) {\n ui.info(\"Cancelled.\");\n return;\n }\n }\n } catch {\n // If we can't fetch, proceed anyway\n }\n }\n\n const spin = ui.spinner(\"Setting PGP key...\");\n\n try {\n const { apiFetch, extractRateLimit } = await import(\"../lib/api.js\");\n const res = await apiFetch(`/api/v1/recipient/${encodeURIComponent(id)}/pgp`, {\n method: \"PUT\",\n body: JSON.stringify({\n public_key: publicKey,\n name: options.name,\n }),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}));\n throw new Error((err as { error?: { message?: string } })?.error?.message || \"Failed to set PGP key\");\n }\n\n const rateLimit = extractRateLimit(res);\n const data = (await res.json()) as { data?: { pgp_fingerprint?: string } };\n spin.succeed(\"PGP key set successfully.\");\n if (data.data?.pgp_fingerprint) {\n ui.info(`Fingerprint: ${data.data.pgp_fingerprint}`);\n }\n ui.showRateLimit(rateLimit);\n } catch (err) {\n spin.fail(\"Failed to set PGP key.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\npgpCommand\n .command(\"remove <id>\")\n .alias(\"rm\")\n .description(\"Remove PGP key from a recipient\")\n .action(async (id: string) => {\n requireAuth();\n const spin = ui.spinner(\"Removing PGP key...\");\n\n try {\n const result = await apiDelete(`/api/v1/recipient/${encodeURIComponent(id)}/pgp`);\n spin.succeed(\"PGP key removed.\");\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to remove PGP key.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { requireAuth, apiGetList, apiGet, apiPost, apiDelete } from \"../lib/api.js\";\nimport { fetchPlanInfo, assertCountLimit } from \"../lib/limits.js\";\nimport * as ui from \"../lib/ui.js\";\nimport type { DomainItem } from \"../types/api.js\";\n\nexport const domainCommand = new Command(\"domain\")\n .alias(\"domains\")\n .description(\"Manage custom domains\");\n\n// List domains\ndomainCommand\n .command(\"list\")\n .alias(\"ls\")\n .description(\"List all domains\")\n // U1: JSON output\n .option(\"--json\", \"Output raw JSON\")\n .action(async (options: { json?: boolean }) => {\n requireAuth();\n const spin = ui.spinner(\"Fetching domains...\");\n\n try {\n const result = await apiGetList<DomainItem>(\"/api/v1/domain\");\n spin.stop();\n\n // U1: JSON output\n if (options.json) {\n ui.outputJson(result.data);\n return;\n }\n\n if (result.data.length === 0) {\n ui.box(\n `${ui.c.secondary(\"No custom domains yet.\")}\\n${ui.c.muted(\"Add one with\")} ${ui.c.accent(\"anonli domain add <domain>\")}`,\n { title: ui.c.info(\"Domains\") }\n );\n return;\n }\n\n ui.table(\n [\"Domain\", \"Status\", \"MX\", \"SPF\", \"DKIM\", \"Created\"],\n result.data.map((d) => [\n d.domain,\n d.verified ? ui.statusBadge(\"verified\", \"active\") : ui.statusBadge(\"pending\", \"inactive\"),\n d.mx_verified ? ui.c.accent(\"✓\") : ui.c.error(\"✗\"),\n d.spf_verified ? ui.c.accent(\"✓\") : ui.c.error(\"✗\"),\n d.dkim_verified ? ui.c.accent(\"✓\") : ui.c.error(\"✗\"),\n ui.formatDate(d.created_at),\n ])\n );\n\n console.log(ui.dim(` ${result.total} domain(s) total`));\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to list domains.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\n// B6: FQDN validation regex\nconst FQDN_RE = /^(?:[a-z0-9](?:[a-z0-9\\-]{0,61}[a-z0-9])?\\.)+[a-z]{2,}$/i;\n\n// Add domain\ndomainCommand\n .command(\"add <domain>\")\n .description(\"Add a custom domain\")\n .action(async (domain: string) => {\n requireAuth();\n\n // B6: Validate domain format before API call\n if (!FQDN_RE.test(domain)) {\n ui.error(`Invalid domain: \"${domain}\". Please enter a valid fully-qualified domain name (e.g. mail.example.com).`);\n process.exit(1);\n }\n\n // Check plan limits before adding\n const limitSpin = ui.spinner(\"Checking plan limits...\");\n const plan = await fetchPlanInfo();\n limitSpin.stop();\n assertCountLimit(\"domain\", plan.domains.used, plan.domains.limit);\n\n const spin = ui.spinner(\"Adding domain...\");\n\n try {\n const result = await apiPost<DomainItem>(\"/api/v1/domain\", {\n domain: domain.toLowerCase(),\n });\n spin.succeed(`Added: ${ui.c.accent(result.data.domain)}`);\n\n ui.spacer();\n ui.sectionTitle(\"DNS Records to Configure\");\n ui.spacer();\n\n // Show DNS records\n console.log(ui.c.secondary(\"1. Ownership TXT record:\"));\n console.log(` Host: ${ui.c.accent(result.data.domain)}`);\n console.log(` Value: ${ui.c.primary(`anon.li=${result.data.verification_token}`)}`);\n ui.spacer();\n\n console.log(ui.c.secondary(\"2. MX record:\"));\n console.log(` Host: ${ui.c.accent(result.data.domain)}`);\n console.log(` Value: ${ui.c.primary(\"mx.anon.li\")} (priority 10)`);\n ui.spacer();\n\n console.log(ui.c.secondary(\"3. SPF TXT record:\"));\n console.log(` Host: ${ui.c.accent(result.data.domain)}`);\n console.log(` Value: ${ui.c.primary(\"v=spf1 include:anon.li ~all\")}`);\n ui.spacer();\n\n if (result.data.dkim_selector && result.data.dkim_public_key) {\n const cleanKey = result.data.dkim_public_key\n .replace(/-----BEGIN PUBLIC KEY-----/g, \"\")\n .replace(/-----END PUBLIC KEY-----/g, \"\")\n .replace(/[\\n\\r\\s]/g, \"\");\n\n console.log(ui.c.secondary(\"4. DKIM TXT record:\"));\n console.log(` Host: ${ui.c.accent(`${result.data.dkim_selector}._domainkey.${result.data.domain}`)}`);\n console.log(` Value: ${ui.c.primary(`v=DKIM1; k=rsa; p=${cleanKey}`)}`);\n ui.spacer();\n }\n\n ui.info(`Run ${ui.c.accent(`anonli domain verify ${result.data.id}`)} after configuring DNS.`);\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to add domain.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\n// Verify domain\ndomainCommand\n .command(\"verify <id>\")\n .description(\"Verify domain DNS records\")\n .action(async (id: string) => {\n requireAuth();\n const spin = ui.spinner(\"Checking DNS records...\");\n\n try {\n const result = await apiPost<{\n verified: boolean;\n ownership_verified: boolean;\n mx_verified: boolean;\n spf_verified: boolean;\n dkim_verified: boolean;\n }>(`/api/v1/domain/${encodeURIComponent(id)}/verify`);\n\n spin.stop();\n\n const d = result.data;\n const statusIcon = (ok: boolean) => ok ? ui.c.accent(\"✓\") : ui.c.error(\"✗\");\n\n ui.header(\"DNS Verification Results\");\n ui.spacer();\n console.log(` Ownership: ${statusIcon(d.ownership_verified)}`);\n console.log(` MX: ${statusIcon(d.mx_verified)}`);\n console.log(` SPF: ${statusIcon(d.spf_verified)}`);\n console.log(` DKIM: ${statusIcon(d.dkim_verified)}`);\n ui.spacer();\n\n if (d.verified) {\n ui.successBox(\"Domain Verified\", \"All DNS records are correctly configured.\");\n } else {\n ui.warn(\"Some DNS records are missing or incorrect. Check your DNS configuration.\");\n }\n\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to verify domain.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\n// Show domain info\ndomainCommand\n .command(\"info <id>\")\n .alias(\"get\")\n .description(\"Show domain details and DNS records\")\n .action(async (id: string) => {\n requireAuth();\n const spin = ui.spinner(\"Fetching domain...\");\n\n try {\n const result = await apiGet<DomainItem & { dns_records: Record<string, unknown> }>(\n `/api/v1/domain/${encodeURIComponent(id)}`\n );\n spin.stop();\n\n const d = result.data;\n ui.header(`Domain: ${d.domain}`);\n ui.spacer();\n\n ui.keyValue(\"ID\", d.id);\n ui.keyValue(\"Status\", d.verified ? \"Verified\" : \"Pending\");\n ui.keyValue(\"Ownership\", d.ownership_verified ? \"✓\" : \"✗\");\n ui.keyValue(\"MX\", d.mx_verified ? \"✓\" : \"✗\");\n ui.keyValue(\"SPF\", d.spf_verified ? \"✓\" : \"✗\");\n ui.keyValue(\"DKIM\", d.dkim_verified ? \"✓\" : \"✗\");\n ui.keyValue(\"Created\", ui.formatDate(d.created_at));\n\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to fetch domain.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\n// Delete domain\ndomainCommand\n .command(\"delete <id>\")\n .alias(\"rm\")\n .description(\"Delete a domain\")\n .option(\"-f, --force\", \"Skip confirmation\")\n .action(async (id: string, options) => {\n requireAuth();\n\n if (!options.force) {\n const confirmed = await ui.confirm(\n `Delete domain ${id}? This will also delete all aliases on this domain.`\n );\n if (!confirmed) {\n ui.info(\"Cancelled.\");\n return;\n }\n }\n\n const spin = ui.spinner(\"Deleting domain...\");\n\n try {\n const result = await apiDelete(`/api/v1/domain/${encodeURIComponent(id)}`);\n spin.succeed(\"Domain deleted.\");\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to delete domain.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\n// Regenerate DKIM\ndomainCommand\n .command(\"dkim <id>\")\n .description(\"Regenerate DKIM keys\")\n .action(async (id: string) => {\n requireAuth();\n const spin = ui.spinner(\"Regenerating DKIM keys...\");\n\n try {\n const result = await apiPost<{\n id: string;\n domain: string;\n dkim_selector: string;\n dkim_record: { type: string; host: string; value: string };\n }>(`/api/v1/domain/${encodeURIComponent(id)}/dkim`);\n\n spin.succeed(\"DKIM keys regenerated.\");\n ui.spacer();\n\n const rec = result.data.dkim_record;\n console.log(ui.c.secondary(\"Update your DKIM TXT record:\"));\n console.log(` Host: ${ui.c.accent(rec.host)}`);\n console.log(` Value: ${ui.c.primary(rec.value)}`);\n\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to regenerate DKIM keys.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { requireAuth, apiGetList, apiPost, apiDelete } from \"../lib/api.js\";\nimport * as ui from \"../lib/ui.js\";\nimport type { ApiKeyItem, ApiKeyCreateResponse } from \"../types/api.js\";\n\nexport const apikeyCommand = new Command(\"apikey\")\n .alias(\"api-key\")\n .description(\"Manage API keys\");\n\n// List API keys\napikeyCommand\n .command(\"list\")\n .alias(\"ls\")\n .description(\"List all API keys\")\n // U1: JSON output\n .option(\"--json\", \"Output raw JSON\")\n .action(async (options: { json?: boolean }) => {\n requireAuth();\n const spin = ui.spinner(\"Fetching API keys...\");\n\n try {\n const result = await apiGetList<ApiKeyItem>(\"/api/v1/api-key\");\n spin.stop();\n\n // U1: JSON output\n if (options.json) {\n ui.outputJson(result.data);\n return;\n }\n\n if (result.data.length === 0) {\n ui.box(\n `${ui.c.secondary(\"No API keys yet.\")}\\n${ui.c.muted(\"Create one with\")} ${ui.c.accent(\"anonli apikey create\")}`,\n { title: ui.c.info(\"API Keys\") }\n );\n return;\n }\n\n ui.table(\n [\"Prefix\", \"Label\", \"Created\"],\n result.data.map((k) => [\n ui.c.accent(k.key_prefix + \"...\"),\n k.label || ui.dim(\"(none)\"),\n ui.formatDate(k.created_at),\n ])\n );\n\n console.log(ui.dim(` ${result.total} API key(s) total`));\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to list API keys.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\n// Create API key\napikeyCommand\n .command(\"create\")\n .alias(\"new\")\n .description(\"Create a new API key\")\n .option(\"-l, --label <label>\", \"Label for the key\")\n .action(async (options) => {\n requireAuth();\n const spin = ui.spinner(\"Creating API key...\");\n\n try {\n const result = await apiPost<ApiKeyCreateResponse>(\"/api/v1/api-key\", {\n label: options.label,\n });\n spin.stop();\n\n ui.successBox(\n \"API Key Created\",\n `${ui.c.warning(\"Save this key now - it won't be shown again!\")}\\n\\n${ui.c.accent(result.data.key)}`\n );\n\n if (result.data.label) {\n ui.info(`Label: ${result.data.label}`);\n }\n\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to create API key.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n\n// Delete API key\napikeyCommand\n .command(\"delete <id>\")\n .alias(\"rm\")\n .description(\"Delete an API key\")\n .option(\"-f, --force\", \"Skip confirmation\")\n .action(async (id: string, options) => {\n requireAuth();\n\n if (!options.force) {\n const confirmed = await ui.confirm(`Delete API key ${id}?`);\n if (!confirmed) {\n ui.info(\"Cancelled.\");\n return;\n }\n }\n\n const spin = ui.spinner(\"Deleting API key...\");\n\n try {\n const result = await apiDelete(`/api/v1/api-key/${encodeURIComponent(id)}`);\n spin.succeed(\"API key deleted.\");\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to delete API key.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { loadConfig, saveConfig, maskApiKey, getApiKey, getBaseUrl } from \"../lib/config.js\";\nimport * as ui from \"../lib/ui.js\";\nimport figures from \"figures\";\n\nexport const configCommand = new Command(\"config\")\n .description(\"View or update CLI configuration\")\n .argument(\"[action]\", \"get, set, or validate\")\n .argument(\"[key]\", \"Config key (e.g. baseUrl)\")\n .argument(\"[value]\", \"Value to set\")\n .action(async (action?: string, key?: string, value?: string) => {\n const config = loadConfig();\n\n if (!action || action === \"get\") {\n // Show config\n ui.sectionTitle(\"Configuration\");\n ui.keyValue(\n \"apiKey\",\n config.apiKey ? maskApiKey(config.apiKey) : ui.dim(\"(not set)\")\n );\n ui.keyValue(\"baseUrl\", config.baseUrl);\n return;\n }\n\n // F5: Config validate subcommand\n if (action === \"validate\") {\n ui.header(\"Config Validation\");\n ui.spacer();\n\n const apiKey = getApiKey();\n const baseUrl = getBaseUrl();\n\n // Check API key format\n const keyOk = !!apiKey && apiKey.startsWith(\"ak_\") && apiKey.length > 10;\n console.log(\n ` ${keyOk ? ui.c.success(figures.tick) : ui.c.error(figures.cross)} API key: ${\n apiKey ? maskApiKey(apiKey) : ui.c.error(\"not set\")\n }`\n );\n\n // Check base URL format\n let urlOk = false;\n try {\n new URL(baseUrl);\n urlOk = true;\n } catch {\n // invalid\n }\n console.log(\n ` ${urlOk ? ui.c.success(figures.tick) : ui.c.error(figures.cross)} Base URL: ${baseUrl}`\n );\n\n // Check connectivity + auth\n if (keyOk && urlOk) {\n const spin = ui.spinner(\"Checking API connectivity...\");\n try {\n const res = await fetch(`${baseUrl}/api/v1/me`, {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n });\n\n if (res.ok) {\n const data = (await res.json()) as { data?: { email?: string } };\n spin.succeed(`Authenticated as ${ui.c.accent(data.data?.email ?? \"unknown\")}`);\n } else if (res.status === 401) {\n spin.fail(\"API key is invalid or expired — run `anonli login` to re-authenticate\");\n process.exit(1);\n } else {\n spin.fail(`API returned unexpected status: ${res.status}`);\n process.exit(1);\n }\n } catch (err) {\n spin.fail(`Cannot reach ${baseUrl}: ${err instanceof Error ? err.message : \"network error\"}`);\n process.exit(1);\n }\n } else {\n const issues: string[] = [];\n if (!keyOk) issues.push(\"API key missing or invalid format\");\n if (!urlOk) issues.push(\"Base URL is not a valid URL\");\n ui.spacer();\n ui.errorBox(\"Config Invalid\", issues.join(\"\\n\"), \"Run `anonli login` to set up authentication.\");\n process.exit(1);\n }\n return;\n }\n\n if (action === \"set\") {\n if (!key || !value) {\n ui.error(\"Usage: anonli config set <key> <value>\");\n process.exit(1);\n }\n\n if (key === \"baseUrl\") {\n try {\n new URL(value);\n } catch {\n ui.error(\"Invalid URL format.\");\n process.exit(1);\n }\n config.baseUrl = value;\n saveConfig(config);\n ui.success(`Set baseUrl to ${value}`);\n } else if (key === \"apiKey\") {\n ui.error(\n 'Use \"anonli login\" to set your API key.'\n );\n process.exit(1);\n } else {\n ui.error(`Unknown config key: ${key}`);\n process.exit(1);\n }\n return;\n }\n\n ui.error(`Unknown action: ${action}. Use \"get\", \"set\", or \"validate\".`);\n process.exit(1);\n });\n","import { Command } from \"commander\";\nimport { execSync } from \"node:child_process\";\nimport * as ui from \"../lib/ui.js\";\n\nexport const updateCommand = new Command(\"update\")\n .description(\"Update anonli to the latest version\")\n .action(() => {\n const spin = ui.spinner(\"Updating anonli...\");\n\n try {\n // Detect package manager\n let cmd: string;\n try {\n execSync(\"bun --version\", { stdio: \"ignore\" });\n cmd = \"bun install -g anonli@latest\";\n } catch {\n cmd = \"npm install -g anonli@latest\";\n }\n\n execSync(cmd, { stdio: \"inherit\" });\n spin.stop();\n\n // B4: Verify the new version was actually installed\n try {\n const newVersion = execSync(\"anonli --version\", { encoding: \"utf8\" }).trim();\n ui.successBox(\"Updated\", `anonli is now up to date.\\nInstalled version: ${newVersion}`);\n } catch {\n ui.successBox(\"Updated\", \"anonli was updated. Run `anonli --version` to confirm.\");\n }\n } catch (err) {\n spin.stop();\n ui.errorBox(\n \"Update Failed\",\n err instanceof Error ? err.message : \"Failed to update.\",\n \"Try: npm install -g anonli@latest\"\n );\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport { execFile } from \"node:child_process\";\nimport { requireAuth, apiPost } from \"../lib/api.js\";\nimport * as ui from \"../lib/ui.js\";\n\nconst PRICING = {\n bundle: {\n name: \"Bundle\",\n description: \"Alias + Drop combined\",\n plus: { monthly: \"$6/mo\", yearly: \"$60/yr\" },\n pro: { monthly: \"$12/mo\", yearly: \"$120/yr\" },\n },\n alias: {\n name: \"Alias\",\n description: \"Anonymous email forwarding\",\n plus: { monthly: \"$3/mo\", yearly: \"$30/yr\" },\n pro: { monthly: \"$6/mo\", yearly: \"$60/yr\" },\n },\n drop: {\n name: \"Drop\",\n description: \"Encrypted file sharing\",\n plus: { monthly: \"$3/mo\", yearly: \"$30/yr\" },\n pro: { monthly: \"$6/mo\", yearly: \"$60/yr\" },\n },\n} as const;\n\nfunction openUrl(url: string): void {\n const platform = process.platform;\n let cmd: string;\n let args: string[];\n\n if (platform === \"darwin\") {\n cmd = \"open\"; args = [url];\n } else if (platform === \"win32\") {\n cmd = \"cmd\"; args = [\"/c\", \"start\", \"\", url];\n } else {\n cmd = \"xdg-open\"; args = [url];\n }\n\n // B3: Handle browser open failure gracefully\n execFile(cmd, args, (err) => {\n if (err) {\n ui.warn(`Could not open browser automatically. Visit this URL manually:\\n ${url}`);\n }\n });\n}\n\nfunction showPricingTable(): void {\n ui.header(\"Plans & Pricing\");\n ui.spacer();\n\n const headers = [\"Product\", \"Tier\", \"Monthly\", \"Yearly\"];\n const rows: string[][] = [];\n\n for (const [key, product] of Object.entries(PRICING)) {\n rows.push([\n `${ui.c.accent(product.name)} ${ui.c.muted(`(${key})`)}`,\n ui.c.accent(\"Plus\"),\n product.plus.monthly,\n `${product.plus.yearly} ${ui.c.success(\"(save up to 25%)\")}`,\n ]);\n rows.push([\n \"\",\n ui.c.gold(\"Pro\"),\n product.pro.monthly,\n `${product.pro.yearly} ${ui.c.success(\"(save up to 25%)\")}`,\n ]);\n }\n\n ui.table(headers, rows);\n\n ui.spacer();\n ui.info(\"Subscribe with:\");\n console.log(ui.c.muted(\" anonli subscribe --product bundle --tier plus --frequency monthly\"));\n console.log(ui.c.muted(\" anonli subscribe --product alias --tier pro --frequency yearly\"));\n console.log(ui.c.muted(\" anonli subscribe --product drop --tier plus --frequency yearly --promo CODE\"));\n}\n\ninterface SubscribeOptions {\n product?: string;\n tier?: string;\n frequency?: string;\n promo?: string;\n open?: boolean;\n}\n\nexport const subscribeCommand = new Command(\"subscribe\")\n .description(\"Subscribe to a paid plan\")\n .option(\"--product <product>\", \"Product: bundle, alias, or drop\")\n .option(\"--tier <tier>\", \"Tier: plus or pro\")\n .option(\"--frequency <frequency>\", \"Billing: monthly or yearly\")\n .option(\"--promo <code>\", \"Promotion code\")\n .option(\"--no-open\", \"Don't open checkout URL in browser\")\n .action(async (options: SubscribeOptions) => {\n // If no options provided, show pricing table\n if (!options.product && !options.tier && !options.frequency) {\n showPricingTable();\n return;\n }\n\n // Validate all required options are present\n if (!options.product || !options.tier || !options.frequency) {\n ui.errorBox(\n \"Missing Options\",\n \"All three options are required: --product, --tier, --frequency\",\n \"Run 'anonli subscribe' without options to see available plans.\"\n );\n process.exit(1);\n }\n\n const validProducts = [\"bundle\", \"alias\", \"drop\"];\n const validTiers = [\"plus\", \"pro\"];\n const validFrequencies = [\"monthly\", \"yearly\"];\n\n if (!validProducts.includes(options.product)) {\n ui.error(`Invalid product: ${options.product}. Must be one of: ${validProducts.join(\", \")}`);\n process.exit(1);\n }\n if (!validTiers.includes(options.tier)) {\n ui.error(`Invalid tier: ${options.tier}. Must be one of: ${validTiers.join(\", \")}`);\n process.exit(1);\n }\n if (!validFrequencies.includes(options.frequency)) {\n ui.error(`Invalid frequency: ${options.frequency}. Must be one of: ${validFrequencies.join(\", \")}`);\n process.exit(1);\n }\n\n requireAuth();\n\n const spin = ui.spinner(\"Creating checkout session...\");\n\n try {\n const body: Record<string, string> = {\n product: options.product,\n tier: options.tier,\n frequency: options.frequency,\n };\n\n if (options.promo) {\n body.promoCode = options.promo;\n }\n\n const result = await apiPost<{ url: string }>(\"/api/v1/checkout\", body);\n spin.stop();\n\n const url = result.data.url;\n\n ui.successBox(\n \"Checkout Ready\",\n `${ui.c.secondary(\"Complete your subscription in the browser:\")}\\n${ui.link(url)}`\n );\n\n if (options.open !== false) {\n openUrl(url);\n ui.info(\"Opening checkout in your default browser...\");\n }\n\n ui.showRateLimit(result.rateLimit);\n } catch (err) {\n spin.fail(\"Failed to create checkout session.\");\n ui.error(err instanceof Error ? err.message : \"Unknown error\");\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport * as ui from \"../lib/ui.js\";\n\nconst BASH_COMPLETION = `# anonli bash completion\n# Add to ~/.bashrc: source <(anonli completions bash)\n_anonli_completions() {\n local cur prev words cword\n _init_completion 2>/dev/null || {\n COMPREPLY=()\n cur=\"\\${COMP_WORDS[COMP_CWORD]}\"\n prev=\"\\${COMP_WORDS[COMP_CWORD-1]}\"\n }\n\n local commands=\"login logout whoami drop alias recipient domain apikey config update subscribe completions\"\n local drop_cmds=\"upload list info download delete toggle share\"\n local alias_cmds=\"new list delete toggle update stats\"\n local recipient_cmds=\"list add delete default verify pgp\"\n local domain_cmds=\"list add verify info delete dkim\"\n local apikey_cmds=\"list create delete\"\n local config_cmds=\"get set validate\"\n\n case \"\\${COMP_WORDS[1]}\" in\n drop)\n COMPREPLY=($(compgen -W \"\\${drop_cmds}\" -- \"\\${cur}\"))\n ;;\n alias)\n COMPREPLY=($(compgen -W \"\\${alias_cmds}\" -- \"\\${cur}\"))\n ;;\n recipient|recipients)\n COMPREPLY=($(compgen -W \"\\${recipient_cmds}\" -- \"\\${cur}\"))\n ;;\n domain|domains)\n COMPREPLY=($(compgen -W \"\\${domain_cmds}\" -- \"\\${cur}\"))\n ;;\n apikey|api-key)\n COMPREPLY=($(compgen -W \"\\${apikey_cmds}\" -- \"\\${cur}\"))\n ;;\n config)\n COMPREPLY=($(compgen -W \"\\${config_cmds}\" -- \"\\${cur}\"))\n ;;\n *)\n COMPREPLY=($(compgen -W \"\\${commands}\" -- \"\\${cur}\"))\n ;;\n esac\n}\ncomplete -F _anonli_completions anonli\n`;\n\nconst ZSH_COMPLETION = `# anonli zsh completion\n# Add to ~/.zshrc: source <(anonli completions zsh)\n_anonli() {\n local state\n typeset -A opt_args\n\n _arguments \\\\\n '1: :->command' \\\\\n '*: :->args'\n\n case \\$state in\n command)\n local commands=(\n 'login:Authenticate with your API key'\n 'logout:Remove stored credentials'\n 'whoami:Show current user info'\n 'drop:Encrypted file drops'\n 'alias:Manage email aliases'\n 'recipient:Manage email recipients'\n 'domain:Manage custom domains'\n 'apikey:Manage API keys'\n 'config:View or update CLI configuration'\n 'update:Update anonli to latest version'\n 'subscribe:Subscribe to a paid plan'\n 'completions:Generate shell completion script'\n )\n _describe 'command' commands\n ;;\n args)\n case \\$words[2] in\n drop)\n local drop_cmds=(\n 'upload:Create an encrypted drop'\n 'list:List your drops'\n 'info:View drop details'\n 'download:Download and decrypt a drop'\n 'delete:Delete a drop'\n 'toggle:Toggle enabled/disabled state'\n 'share:Reconstruct a share URL'\n )\n _describe 'drop command' drop_cmds\n ;;\n alias)\n local alias_cmds=(\n 'new:Create a new alias'\n 'list:List all aliases'\n 'delete:Delete an alias'\n 'toggle:Toggle alias active state'\n 'update:Update alias settings'\n 'stats:Show forwarding statistics'\n )\n _describe 'alias command' alias_cmds\n ;;\n config)\n local config_cmds=('get:Show config' 'set:Update config value' 'validate:Check config health')\n _describe 'config command' config_cmds\n ;;\n esac\n ;;\n esac\n}\ncompdef _anonli anonli\n`;\n\nconst FISH_COMPLETION = `# anonli fish completion\n# Add to ~/.config/fish/completions/anonli.fish or run: anonli completions fish | source\n\n# Disable file completions by default\ncomplete -c anonli -f\n\n# Main commands\ncomplete -c anonli -n '__fish_use_subcommand' -a login -d 'Authenticate with your API key'\ncomplete -c anonli -n '__fish_use_subcommand' -a logout -d 'Remove stored credentials'\ncomplete -c anonli -n '__fish_use_subcommand' -a whoami -d 'Show current user info'\ncomplete -c anonli -n '__fish_use_subcommand' -a drop -d 'Encrypted file drops'\ncomplete -c anonli -n '__fish_use_subcommand' -a alias -d 'Manage email aliases'\ncomplete -c anonli -n '__fish_use_subcommand' -a recipient -d 'Manage email recipients'\ncomplete -c anonli -n '__fish_use_subcommand' -a domain -d 'Manage custom domains'\ncomplete -c anonli -n '__fish_use_subcommand' -a apikey -d 'Manage API keys'\ncomplete -c anonli -n '__fish_use_subcommand' -a config -d 'View or update CLI configuration'\ncomplete -c anonli -n '__fish_use_subcommand' -a update -d 'Update anonli to latest version'\ncomplete -c anonli -n '__fish_use_subcommand' -a subscribe -d 'Subscribe to a paid plan'\ncomplete -c anonli -n '__fish_use_subcommand' -a completions -d 'Generate shell completion script'\n\n# Quiet flag\ncomplete -c anonli -s q -l quiet -d 'Suppress non-essential output'\n\n# drop subcommands\ncomplete -c anonli -n '__fish_seen_subcommand_from drop' -a upload -d 'Create an encrypted drop'\ncomplete -c anonli -n '__fish_seen_subcommand_from drop' -a list -d 'List your drops'\ncomplete -c anonli -n '__fish_seen_subcommand_from drop' -a info -d 'View drop details'\ncomplete -c anonli -n '__fish_seen_subcommand_from drop' -a download -d 'Download and decrypt a drop'\ncomplete -c anonli -n '__fish_seen_subcommand_from drop' -a delete -d 'Delete a drop'\ncomplete -c anonli -n '__fish_seen_subcommand_from drop' -a toggle -d 'Toggle enabled/disabled state'\ncomplete -c anonli -n '__fish_seen_subcommand_from drop' -a share -d 'Reconstruct a share URL'\n\n# alias subcommands\ncomplete -c anonli -n '__fish_seen_subcommand_from alias' -a new -d 'Create a new alias'\ncomplete -c anonli -n '__fish_seen_subcommand_from alias' -a list -d 'List all aliases'\ncomplete -c anonli -n '__fish_seen_subcommand_from alias' -a delete -d 'Delete an alias'\ncomplete -c anonli -n '__fish_seen_subcommand_from alias' -a toggle -d 'Toggle alias active state'\ncomplete -c anonli -n '__fish_seen_subcommand_from alias' -a update -d 'Update alias settings'\ncomplete -c anonli -n '__fish_seen_subcommand_from alias' -a stats -d 'Show forwarding statistics'\n\n# config subcommands\ncomplete -c anonli -n '__fish_seen_subcommand_from config' -a get -d 'Show current config'\ncomplete -c anonli -n '__fish_seen_subcommand_from config' -a set -d 'Update a config value'\ncomplete -c anonli -n '__fish_seen_subcommand_from config' -a validate -d 'Check config health'\n\n# completions shells\ncomplete -c anonli -n '__fish_seen_subcommand_from completions' -a bash -d 'Bash completion script'\ncomplete -c anonli -n '__fish_seen_subcommand_from completions' -a zsh -d 'Zsh completion script'\ncomplete -c anonli -n '__fish_seen_subcommand_from completions' -a fish -d 'Fish completion script'\n`;\n\nexport const completionsCommand = new Command(\"completions\")\n .description(\"Generate shell completion script\")\n .argument(\"<shell>\", \"Shell type: bash, zsh, or fish\")\n .addHelpText(\"after\", `\nExamples:\n # bash — add to ~/.bashrc\n source <(anonli completions bash)\n\n # zsh — add to ~/.zshrc\n source <(anonli completions zsh)\n\n # fish — save to completions directory\n anonli completions fish > ~/.config/fish/completions/anonli.fish`)\n .action((shell: string) => {\n switch (shell.toLowerCase()) {\n case \"bash\":\n process.stdout.write(BASH_COMPLETION);\n break;\n case \"zsh\":\n process.stdout.write(ZSH_COMPLETION);\n break;\n case \"fish\":\n process.stdout.write(FISH_COMPLETION);\n break;\n default:\n ui.error(`Unknown shell: ${shell}. Supported shells: bash, zsh, fish`);\n process.exit(1);\n }\n });\n","import semver from \"semver\";\nimport { loadConfig, saveConfig } from \"./config.js\";\nimport { updateNotice } from \"./ui.js\";\n\nconst CACHE_DURATION_MS = 24 * 60 * 60 * 1000; // 24 hours\n\nexport async function checkForUpdates(currentVersion: string): Promise<void> {\n // Skip version check in CI/CD or when explicitly disabled (F8)\n if (process.env.ANONLI_NO_UPDATE_CHECK) return;\n\n const config = loadConfig();\n\n // Check if we have a cached result that's still fresh\n if (\n config.lastVersionCheck &&\n config.latestVersion &&\n Date.now() - config.lastVersionCheck < CACHE_DURATION_MS\n ) {\n printUpdateNotice(currentVersion, config.latestVersion);\n return;\n }\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 3000);\n\n const res = await fetch(\"https://registry.npmjs.org/anonli/latest\", {\n signal: controller.signal,\n });\n clearTimeout(timeout);\n\n if (!res.ok) return;\n\n const data = (await res.json()) as { version: string };\n const latestVersion = data.version;\n\n // Cache the result\n config.lastVersionCheck = Date.now();\n config.latestVersion = latestVersion;\n saveConfig(config);\n\n printUpdateNotice(currentVersion, latestVersion);\n } catch {\n // Silently fail — not critical\n }\n}\n\nfunction printUpdateNotice(current: string, latest: string): void {\n if (semver.gt(latest, current)) {\n updateNotice(current, latest);\n }\n}\n"],"mappings":"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","names":["init_config","path","init_config","Command","init_config","chalk","init_config","info","desc","chalk","chalk","prompt","init_config","success","init_config","Command","Command","init_config","Command","Command","Command","Command","fs","os","path","info","init_config","fs","path","Command","os","baseUrl","Command","Command","Command","Command","Command","fs","path","init_config","path","fs","Command","Command","Command","Command","init_config","Command","Command","init_config","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","fs","path","apiFetch","extractRateLimit","Command","Command","Command","Command","init_config","Command","figures","Command","Command","Command","Command","Command","Command","Command","init_config","init_config","Command","success"]}