@liteio/storage-cli
v3.0.0
Published
CLI for Storage API — upload, download, and share files from your terminal
Maintainers
Readme
@liteio/storage-cli
The official CLI for Liteio Storage API — upload, download, organize, and share files from your terminal.
Zero dependencies. Single file. Works with Node 18+, Bun, and Deno.
npx @liteio/storage-cli --helpWhy?
- No SDK needed — one command to upload, download, or share any file
- Pipe-friendly — reads stdin, writes stdout, uses proper exit codes
- Works everywhere — Node.js, Bun, Deno, CI/CD, Docker, cron
- Zero dependencies — single
.mjsfile, nothing to install or audit - Secure by default — OAuth PKCE login, scoped API keys,
0600token permissions
Install
# Run without installing (recommended for trying it out)
npx @liteio/storage-cli
bunx @liteio/storage-cli
# Install globally for everyday use
npm install -g @liteio/storage-cliAfter installing globally, the storage command is available everywhere:
storage login
storage put photo.jpg images/
storage share images/photo.jpg --expires 7dRunning with Deno
deno run --allow-all npm:@liteio/storage-cli --help
deno run --allow-all npm:@liteio/storage-cli lsYou can also create a shell alias for convenience:
alias storage="deno run --allow-all npm:@liteio/storage-cli"Quick start
# 1. Authenticate (opens browser, OAuth 2.0 PKCE — takes 5 seconds)
storage login
# 2. Upload a file
storage put report.pdf docs/report.pdf
# 3. List your files
storage ls docs/
# 4. Share it with anyone (link expires in 1 hour by default)
storage share docs/report.pdf
# → https://storage.liteio.dev/s/Xk9mP2nQ4rWz8AbCdEf3g
# 5. Download it back
storage get docs/report.pdf
# 6. Print a file to stdout (great for piping)
storage cat docs/data.json | jq '.items'Commands
Authentication
| Command | Description |
|---------|-------------|
| storage login | Authenticate via browser (OAuth 2.0 with PKCE) |
| storage logout | Remove saved credentials |
| storage token | Show current token source and prefix |
| storage token <token> | Save a token directly (useful for CI or headless servers) |
File operations
| Command | Description |
|---------|-------------|
| storage ls [path] | List files and directories. No args = root. |
| storage put <file> [path] | Upload a file. Use - to read from stdin. |
| storage get <path> [dest] | Download a file. Use - to write to stdout. |
| storage cat <path> | Print file contents to stdout (alias for get <path> -) |
| storage rm <path...> | Delete one or more files |
| storage mv <from> <to> | Move or rename a file (server-side, instant) |
Sharing & discovery
| Command | Description |
|---------|-------------|
| storage share <path> | Create a signed share URL (default: 1 hour) |
| storage find <query> | Search files by name |
| storage stat | Show total files and storage usage |
API keys
| Command | Description |
|---------|-------------|
| storage key create <name> | Create an API key (shown once — save it!) |
| storage key list | List all API keys |
| storage key rm <id> | Revoke an API key |
Usage examples
Upload
# Upload a file (destination = same filename at root)
storage put photo.jpg
# Upload to a specific path
storage put photo.jpg images/vacation/photo.jpg
# Upload to a directory (trailing slash appends the filename)
storage put photo.jpg images/
# Upload from stdin — great for piping
echo '{"key": "value"}' | storage put - config/settings.json
# Pipe command output directly to storage
curl -s https://example.com/data.csv | storage put - reports/latest.csvDownload
# Download to current directory (keeps original filename)
storage get docs/report.pdf
# Download to a specific path
storage get docs/report.pdf ~/Downloads/report.pdf
# Download to stdout (use - as destination)
storage cat docs/data.json | jq '.items[] | .name'Share
Share links are short, opaque, and expire automatically. They reveal nothing about your account or file paths.
# Create a share link (default: expires in 1 hour)
storage share docs/report.pdf
# → https://storage.liteio.dev/s/Xk9mP2nQ4rWz8AbCdEf3g
# Custom expiration
storage share docs/report.pdf --expires 30m
storage share docs/report.pdf --expires 7d
# Get the URL as JSON (useful for scripting)
storage share docs/report.pdf --json | jq -r '.url'Duration format: 30s, 15m, 2h, 7d, or plain seconds (3600).
Delete
# Delete a single file
storage rm docs/old-report.pdf
# Delete a directory recursively (prompts for confirmation)
storage rm logs/ --recursive
# Skip confirmation prompt
storage rm logs/ --recursive --forceSearch
# Search by filename
storage find quarterly
# Get results as JSON for scripting
storage find "*.pdf" --json | jq '.results[].path'Move / rename
# Rename a file
storage mv drafts/post.md published/post.md
# Move to another directory
storage mv old/report.pdf archive/report.pdfAPI keys
Use API keys for CI/CD, scripts, and automation — they don't expire (unless you set one) and can be restricted to specific path prefixes.
# Create a key (full access)
storage key create deploy-bot
# Create a key restricted to a path prefix
storage key create uploads-only --prefix uploads/
# List all keys
storage key list
# Revoke a key by ID
storage key rm ak_abc123def456Global flags
| Flag | Short | Description |
|------|-------|-------------|
| --json | -j | Output as JSON (machine-readable) |
| --quiet | -q | Suppress non-essential output |
| --token <token> | -t | Override authentication token |
| --endpoint <url> | -e | Override API base URL |
| --no-color | | Disable colored output |
| --version | -v | Show version |
| --help | -h | Show help |
Configuration
The CLI resolves configuration in this order (first match wins):
- CLI flags (
--token,--endpoint) - Environment variables (
STORAGE_TOKEN,STORAGE_ENDPOINT) - Token file (
~/.config/storage/token) — written bystorage login - Config file (
~/.config/storage/config)
Environment variables
# Use an API key for CI/CD pipelines
export STORAGE_TOKEN=sk_your_api_key_here
# Point to a different endpoint (e.g. staging)
export STORAGE_ENDPOINT=https://storage.liteio.devConfig file
Located at ~/.config/storage/config (or $XDG_CONFIG_HOME/storage/config):
endpoint=https://storage.liteio.devJSON output
Every command supports --json for machine-readable output — perfect for scripting:
# List files as JSON
storage ls docs/ --json
# Extract file names with jq
storage ls docs/ --json | jq '.entries[].name'
# Get storage usage as a number
storage stat --json | jq '.bytes'Pipes & scripting
The CLI is designed as a well-behaved Unix tool: it reads stdin, writes stdout, sends status messages to stderr, and uses meaningful exit codes.
# Pipe a database dump directly to storage (no temp files)
pg_dump mydb | gzip | storage put - backups/db/$(date +%F).sql.gz
# Process downloaded JSON
storage cat docs/users.json | jq '.[] | select(.active)' > active.json
# Batch upload all PNGs in a directory
find ./images -name '*.png' -exec sh -c \
'storage put "$1" images/"$(basename "$1")"' _ {} \;CI/CD
# GitHub Actions example
- name: Upload build artifacts
env:
STORAGE_TOKEN: ${{ secrets.STORAGE_TOKEN }}
run: |
npx @liteio/storage-cli put ./dist/bundle.js cdn/bundle.js
npx @liteio/storage-cli put ./dist/style.css cdn/style.cssExit codes
Scripts can react to specific error types:
| Code | Name | When | |------|------|------| | 0 | Success | Operation completed normally | | 1 | Error | Unspecified runtime error | | 2 | Usage | Bad arguments or flags | | 3 | Auth | Missing or invalid token | | 4 | Not found | File does not exist | | 5 | Conflict | Name collision | | 6 | Permission | Token lacks access to this path | | 7 | Network | Connection failed or timed out |
storage get backups/latest.sql.gz .
case $? in
0) echo "restored ok" ;;
4) echo "no backup found" ;;
3) echo "auth failed — run: storage login" ;;
7) echo "network error — retry later" ;;
esacRuntime compatibility
| Runtime | Version | Install |
|---------|---------|---------|
| Node.js | 18+ | npx @liteio/storage-cli |
| Bun | 1.0+ | bunx @liteio/storage-cli |
| Deno | 1.35+ | deno run --allow-all npm:@liteio/storage-cli |
The CLI uses only Node.js built-in modules (node:crypto, node:fs, node:http, node:os, node:path, node:child_process, node:buffer, node:process) — zero external dependencies.
License
MIT
