UNPKG

@pushduck/cli

Version:

Official CLI for pushduck - Add S3 upload functionality to your Next.js project

351 lines (261 loc) • 9.44 kB
# Pushduck CLI [![NPM Version](https://img.shields.io/npm/v/@pushduck/cli?style=flat&colorA=18181B&colorB=374151)](https://www.npmjs.com/package/@pushduck/cli) [![NPM Downloads](https://img.shields.io/npm/dm/@pushduck/cli?style=flat&colorA=18181B&colorB=374151)](https://www.npmjs.com/package/@pushduck/cli) [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue?style=flat&colorA=18181B&colorB=3178C6)](https://www.typescriptlang.org/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=flat&colorA=18181B&colorB=F59E0B)](https://opensource.org/licenses/MIT) [![Discord](https://img.shields.io/badge/Discord-Join%20Community-7289DA?style=flat&colorA=18181B&colorB=7289DA)](https://discord.gg/pushduck) [![Twitter](https://img.shields.io/badge/Twitter-Share%20on%20Twitter-1DA1F2?style=flat&colorA=18181B&colorB=1DA1F2)](https://twitter.com/intent/tweet?text=Just%20discovered%20%40pushduck%20-%20the%20fastest%20way%20to%20add%20file%20uploads%20to%20any%20web%20app!%20šŸ¦†%20https%3A//github.com/abhay-ramesh/pushduck) Zero-configuration setup for Next.js file uploads. Get production-ready S3 uploads working in under 2 minutes. ## Quick Start ```bash npx @pushduck/cli@latest init ``` That's it! The CLI will guide you through setting up: - āœ… Provider configuration (AWS S3, Cloudflare R2, etc.) - āœ… API route generation with TypeScript - āœ… Example upload components - āœ… Environment variable setup - āœ… Bucket creation (optional) ## Commands ### `init` - Initialize Your Project ```bash npx @pushduck/cli@latest init [options] ``` **Options:** - `--provider <type>` - Skip provider selection (aws|cloudflare-r2|digitalocean|minio|gcs) - `--skip-examples` - Don't generate example components - `--skip-bucket` - Don't create S3 bucket automatically - `--api-path <path>` - Custom API route path (default: `/api/upload`) - `--dry-run` - Show what would be created without creating - `--verbose` - Show detailed output **Examples:** ```bash # Interactive setup with all prompts npx @pushduck/cli@latest init # Use AWS S3 directly, skip examples npx @pushduck/cli@latest init --provider aws --skip-examples # Custom API path npx @pushduck/cli@latest init --api-path /api/files # Preview without creating files npx @pushduck/cli@latest init --dry-run ``` ### `add` - Add Upload Routes ```bash npx @pushduck/cli@latest add ``` Add new upload routes to your existing configuration. Interactive route builder helps you: - Define file types and validation - Set up middleware and authentication - Configure upload destinations - Generate TypeScript types ### `test` - Validate Setup ```bash npx @pushduck/cli@latest test [--verbose] ``` Validates your current configuration: - āœ… Environment variables - āœ… S3 bucket connectivity - āœ… CORS configuration - āœ… API route functionality - āœ… TypeScript compilation ## What Gets Created The CLI generates a complete, production-ready setup: ``` your-project/ ā”œā”€ā”€ app/api/upload/route.ts # Type-safe upload API ā”œā”€ā”€ app/upload/page.tsx # Demo upload page ā”œā”€ā”€ components/ui/ │ ā”œā”€ā”€ upload-button.tsx # Simple upload button │ ā”œā”€ā”€ upload-dropzone.tsx # Drag & drop component │ └── file-preview.tsx # File preview component ā”œā”€ā”€ lib/upload-client.ts # Type-safe upload client ā”œā”€ā”€ .env.local # Environment variables └── .env.example # Environment template ``` ### Generated API Route ```typescript // app/api/upload/route.ts import { createUploadRouter, uploadSchema } from 'pushduck/server' export const router = createUploadRouter({ imageUpload: uploadSchema({ image: { maxSize: "5MB", maxCount: 1, formats: ["jpeg", "png", "webp"] } }).middleware(async ({ req }) => { // Add your authentication logic const userId = await getUserId(req) return { userId, folder: `uploads/${userId}` } }), documentUpload: uploadSchema({ file: { maxSize: "10MB", maxCount: 5, allowedTypes: ["application/pdf", "text/plain"] } }).middleware(async ({ req }) => { const userId = await getUserId(req) return { userId, folder: `documents/${userId}` } }) }) export type AppRouter = typeof router export const { GET, POST } = router ``` ### Generated Upload Client ```typescript // lib/upload-client.ts import { createUploadClient } from 'pushduck/client' import type { AppRouter } from '@/app/api/upload/route' export const upload = createUploadClient<AppRouter>({ endpoint: '/api/upload' }) // Property-based access with full type safety export const { imageUpload, documentUpload } = upload ``` ### Generated Components ```typescript // components/ui/upload-button.tsx 'use client' import { upload } from '@/lib/upload-client' export function UploadButton() { const { uploadFiles, uploadedFiles, isUploading, progress } = upload.imageUpload() return ( <div> <input type="file" onChange={(e) => uploadFiles(e.target.files)} disabled={isUploading} /> {isUploading && <div>Progress: {progress}%</div>} {uploadedFiles.map(file => ( <img key={file.key} src={file.url} alt="Uploaded" /> ))} </div> ) } ``` ## Provider Support The CLI supports all major S3-compatible providers: - **AWS S3** - The original and most feature-complete - **Cloudflare R2** - Global edge network, S3-compatible - **DigitalOcean Spaces** - Simple and affordable - **Google Cloud Storage** - Enterprise-grade with global reach - **MinIO** - Self-hosted, open source S3 alternative ### Provider-Specific Setup Each provider has tailored setup: ```bash # AWS S3 with automatic IAM policy creation npx @pushduck/cli@latest init --provider aws # Cloudflare R2 with edge optimization npx @pushduck/cli@latest init --provider cloudflare-r2 # DigitalOcean Spaces with CDN setup npx @pushduck/cli@latest init --provider digitalocean # MinIO for local development npx @pushduck/cli@latest init --provider minio ``` ## Interactive Setup Flow The CLI provides a guided setup experience: ``` ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ │ │ šŸš€ Welcome to Pushduck │ │ │ │ Let's get your file uploads working in 2 minutes! │ │ │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ šŸ” Detecting your project... āœ“ Next.js App Router detected āœ“ TypeScript configuration found āœ“ No existing upload configuration ? Which cloud storage provider would you like to use? āÆ AWS S3 (recommended) Cloudflare R2 (S3-compatible, global edge) DigitalOcean Spaces (simple, affordable) šŸ”§ Setting up AWS S3... šŸ” Checking for existing credentials... āœ“ Found AWS_ACCESS_KEY_ID āœ“ Found AWS_SECRET_ACCESS_KEY āœ“ Found AWS_REGION ? Enter your S3 bucket name: my-app-uploads ? Create bucket automatically? Yes šŸ› ļø Generating files... ✨ Created files: ā”œā”€ā”€ app/api/upload/route.ts ā”œā”€ā”€ app/upload/page.tsx ā”œā”€ā”€ components/ui/upload-button.tsx ā”œā”€ā”€ lib/upload-client.ts └── .env.example šŸ“¦ Installing dependencies... āœ“ pushduck āœ“ react-dropzone šŸŽ‰ Setup complete! Your uploads are ready. ``` ## Troubleshooting ### CLI Not Found ```bash # If you get "command not found" npm install -g pushduck # Or use npx for one-time usage npx @pushduck/cli@latest@latest init ``` ### Permission Errors ```bash # If you get permission errors during setup sudo npx @pushduck/cli@latest init # Or fix npm permissions npm config set prefix ~/.npm-global export PATH=~/.npm-global/bin:$PATH ``` ### Bucket Creation Failed ```bash # Test your credentials first npx @pushduck/cli@latest test # Skip automatic bucket creation npx @pushduck/cli@latest init --skip-bucket # Create bucket manually, then run: npx @pushduck/cli@latest test ``` ## Advanced Usage ### Non-Interactive Mode ```bash # For CI/CD environments npx @pushduck/cli@latest init \ --provider aws \ --skip-examples \ --api-path /api/upload \ --no-interactive ``` ### Custom Templates ```bash # Use enterprise template with security features npx @pushduck/cli@latest init --template enterprise # Use minimal template for existing projects npx @pushduck/cli@latest init --template minimal ``` ### Monorepo Support ```bash # For monorepos, specify the Next.js app directory cd apps/web npx @pushduck/cli@latest init # Or use the --cwd flag npx @pushduck/cli@latest init --cwd apps/web ``` ## Contributing The CLI is part of the [pushduck monorepo](https://github.com/your-org/pushduck). ```bash # Clone the repository git clone https://github.com/your-org/pushduck.git # Install dependencies pnpm install # Development cd packages/cli pnpm dev # Build pnpm build # Test locally npm link pushduck init ``` ## License MIT Ā© [Abhay Ramesh](https://github.com/abhayramesh)