{"_id":"@carcosa/file-router","name":"@carcosa/file-router","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@carcosa/file-router","version":"0.1.0","private":false,"type":"module","description":"Typed file upload router system for Carcosa - UploadThing competitor","main":"dist/file-router/src/index.js","types":"dist/file-router/src/index.d.ts","exports":{".":{"types":"./dist/file-router/src/index.d.ts","import":"./dist/file-router/src/index.js","require":"./dist/file-router/src/index.js"}},"scripts":{"build":"tsc","dev":"tsc --watch","clean":"rm -rf dist","prebuild":"npm run clean","test":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage"},"dependencies":{"express":"^4.19.2","sharp":"^0.33.5","zod":"^3.23.8","@carcosa/database":"*","jsonwebtoken":"^9.0.2","bcryptjs":"^3.0.3","redis":"^4.6.10","multer":"^1.4.5-lts.1","cors":"^2.8.5","helmet":"^7.1.0","express-rate-limit":"^7.1.5","ws":"^8.14.2","uuid":"^9.0.1","socket.io":"^4.7.5"},"devDependencies":{"typescript":"5.8.3","jest":"^29.7.0","@types/jest":"^29.5.8","ts-jest":"^29.1.1","@types/express":"^4.17.21","@types/jsonwebtoken":"^9.0.5","@types/bcryptjs":"^2.4.6","@types/multer":"^1.4.11","@types/cors":"^2.8.17","@types/ws":"^8.5.10","@types/uuid":"^9.0.7","@types/node":"^20.10.0","supertest":"^6.3.3","@types/supertest":"^6.0.2","@types/socket.io":"^3.0.0"},"peerDependencies":{"react":"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","react-dom":"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"},"keywords":["file-upload","router","typescript","carcosa","uploadthing-competitor"],"author":{"name":"Carcosa Team"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/Seganation/carcosa.git","directory":"packages/file-router"},"homepage":"https://github.com/Seganation/carcosa#readme","bugs":{"url":"https://github.com/Seganation/carcosa/issues"},"gitHead":"f1198793f5e11dfc939a9f99da254b36c9ef1e90","_id":"@carcosa/file-router@0.1.0","_nodeVersion":"24.10.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-pHQ6pq1wU7+XHIb6aAaRsYhN0iiI7d3dOlqXasOoxL0m1rniEa0u+6pYRY0cAEQPDk6/a0MUMjAIu9EbXrhEow==","shasum":"8e21d48217194cf4bbebf2fc71d9629a77af91d9","tarball":"https://registry.npmjs.org/@carcosa/file-router/-/file-router-0.1.0.tgz","fileCount":94,"unpackedSize":679867,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDCr1LegkZzAonJX3BeLkQ+lLO29aKVtZCACcgGXPkUxQIhAOpy6r8xHjnUB9dNIZQoBraAlD28Q7wc+4fMgDcBCpc3"}]},"_npmUser":{"name":"noblerawa","email":"xdniklaus@gmail.com"},"directories":{},"maintainers":[{"name":"noblerawa","email":"xdniklaus@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/file-router_0.1.0_1763935501543_0.25935160552913006"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-23T22:05:01.468Z","0.1.0":"2025-11-23T22:05:01.794Z","modified":"2025-11-23T22:05:02.031Z"},"maintainers":[{"name":"noblerawa","email":"xdniklaus@gmail.com"}],"description":"Typed file upload router system for Carcosa - UploadThing competitor","homepage":"https://github.com/Seganation/carcosa#readme","keywords":["file-upload","router","typescript","carcosa","uploadthing-competitor"],"repository":{"type":"git","url":"git+https://github.com/Seganation/carcosa.git","directory":"packages/file-router"},"author":{"name":"Carcosa Team"},"bugs":{"url":"https://github.com/Seganation/carcosa/issues"},"license":"MIT","readme":"# @carcosa/file-router\n\n**Typed file upload router system for Carcosa - The UploadThing Killer! 🚀**\n\nThis package provides a type-safe, middleware-driven file upload system that matches UploadThing's developer experience while giving you complete control over your storage infrastructure.\n\n## ✨ Features\n\n- **🚀 Type-Safe Routes** - Full TypeScript support with inference\n- **🔒 Middleware Support** - Custom validation, auth, and business logic\n- **📁 File Constraints** - Size, count, and type validation\n- **🎯 Upload Completion** - Handle post-upload processing\n- **🌐 Framework Agnostic** - Works with Express, Next.js, Fastify, and more\n- **⚡ Zero Dependencies** - Lightweight and fast\n\n## 🚀 Quick Start\n\n### 1. Install the Package\n\n```bash\nnpm install @carcosa/file-router\n```\n\n### 2. Create Your Upload Router\n\n```typescript\nimport { createUploadRouter, f } from '@carcosa/file-router';\n\nexport const uploadRouter = createUploadRouter<{\n  userId: string;\n  projectId: string;\n}>();\n\n// Define your routes\nuploadRouter.addRoute(\n  'profileImage',\n  f.imageUploader({ maxFileSize: '2MB', maxFileCount: 1 })\n    .middleware(async ({ req, metadata }) => {\n      // Custom auth logic\n      const userId = req.headers['x-user-id'];\n      if (!userId) throw new Error('Authentication required');\n      \n      return { userId, projectId: 'default' };\n    })\n    .onUploadComplete(async ({ metadata, file }) => {\n      // Post-upload processing\n      console.log(`Profile image uploaded for user ${metadata.userId}`);\n      return { success: true };\n    })\n);\n```\n\n### 3. Use with Express\n\n```typescript\nimport express from 'express';\nimport { createUploadMiddleware } from '@carcosa/file-router';\nimport { uploadRouter } from './upload-router';\n\nconst app = express();\nconst uploadMiddleware = createUploadMiddleware(uploadRouter);\n\napp.post('/api/upload/init', uploadMiddleware.handleUploadInit.bind(uploadMiddleware));\napp.post('/api/upload/complete', uploadMiddleware.handleUploadComplete.bind(uploadMiddleware));\n```\n\n### 4. Use with Next.js\n\n```typescript\n// pages/api/upload/init.ts\nimport { uploadRouter } from '../../../upload-router';\n\nexport default async function handler(req, res) {\n  if (req.method !== 'POST') {\n    return res.status(405).json({ error: 'Method not allowed' });\n  }\n\n  try {\n    const { routeName, metadata } = req.body;\n    const route = uploadRouter.getRoute(routeName);\n    \n    if (!route) {\n      return res.status(404).json({ error: 'Route not found' });\n    }\n\n    // Handle upload initialization\n    // ... implementation details\n  } catch (error) {\n    res.status(500).json({ error: error.message });\n  }\n}\n```\n\n## 🎯 API Reference\n\n### File Type Builders\n\n#### `f.imageUploader(config?)`\nCreates an image uploader with constraints.\n\n```typescript\nf.imageUploader({\n  maxFileSize: '4MB',\n  maxFileCount: 5,\n  maxWidth: 1920,\n  maxHeight: 1080\n})\n```\n\n#### `f.videoUploader(config?)`\nCreates a video uploader with constraints.\n\n```typescript\nf.videoUploader({\n  maxFileSize: '128MB',\n  maxFileCount: 1,\n  maxDuration: 300 // 5 minutes\n})\n```\n\n#### `f.audioUploader(config?)`\nCreates an audio uploader with constraints.\n\n```typescript\nf.audioUploader({\n  maxFileSize: '32MB',\n  maxFileCount: 10,\n  maxDuration: 600 // 10 minutes\n})\n```\n\n#### `f.documentUploader(config?)`\nCreates a document uploader for PDFs, etc.\n\n```typescript\nf.documentUploader({\n  maxFileSize: '16MB',\n  maxFileCount: 20\n})\n```\n\n#### `f.fileUploader(config?)`\nCreates a general file uploader.\n\n```typescript\nf.fileUploader({\n  maxFileSize: '64MB',\n  maxFileCount: 50\n})\n```\n\n### Route Methods\n\n#### `.middleware(fn)`\nAdd custom middleware for validation, auth, or business logic.\n\n```typescript\n.middleware(async ({ req, metadata }) => {\n  // Verify user authentication\n  const token = req.headers.authorization;\n  const user = await verifyToken(token);\n  \n  if (!user) {\n    throw new Error('Unauthorized');\n  }\n  \n  return { userId: user.id, projectId: user.defaultProject };\n})\n```\n\n#### `.onUploadComplete(fn)`\nHandle post-upload processing.\n\n```typescript\n.onUploadComplete(async ({ metadata, file }) => {\n  // Save to database\n  await db.files.create({\n    key: file.key,\n    name: file.name,\n    userId: metadata.userId,\n    projectId: metadata.projectId\n  });\n  \n  // Trigger image processing\n  await processImage(file.key);\n  \n  return { saved: true, processed: true };\n})\n```\n\n## 🔧 Configuration\n\n### File Size Constraints\n- `1B`, `1KB`, `1MB`, `4MB`, `8MB`, `16MB`, `32MB`, `64MB`, `128MB`, `256MB`, `512MB`, `1GB`, `2GB`, `4GB`, `8GB`, `16GB`\n\n### File Type Constraints\n- `image`, `video`, `audio`, `text`, `pdf`, `spreadsheet`, `presentation`, `archive`, `code`, `font`, `model`, `other`\n\n### Route Configuration\n```typescript\ninterface RouteConfig {\n  maxFileSize?: FileSize;\n  maxFileCount?: number;\n  allowedFileTypes?: FileType[];\n  image?: {\n    maxFileSize?: FileSize;\n    maxFileCount?: number;\n    maxWidth?: number;\n    maxHeight?: number;\n  };\n  video?: {\n    maxFileSize?: FileSize;\n    maxFileCount?: number;\n    maxDuration?: number;\n  };\n  audio?: {\n    maxFileSize?: FileSize;\n    maxFileCount?: number;\n    maxDuration?: number;\n  };\n}\n```\n\n## 🚀 Advanced Usage\n\n### Custom File Validation\n\n```typescript\nuploadRouter.addRoute(\n  'customValidation',\n  f.fileUploader()\n    .middleware(async ({ req, metadata }) => {\n      // Custom business logic\n      const user = await getUser(req.headers.authorization);\n      const project = await getProject(req.body.projectId);\n      \n      // Check user permissions\n      if (!user.canUploadToProject(project.id)) {\n        throw new Error('Insufficient permissions');\n      }\n      \n      // Check project limits\n      if (project.uploadCount >= project.maxUploads) {\n        throw new Error('Project upload limit reached');\n      }\n      \n      return { userId: user.id, projectId: project.id };\n    })\n);\n```\n\n### Batch Processing\n\n```typescript\nuploadRouter.addRoute(\n  'batchUpload',\n  f.fileUploader({ maxFileCount: 100 })\n    .onUploadComplete(async ({ metadata, file }) => {\n      // Process multiple files\n      await processBatchFile(file.key, metadata.batchId);\n      \n      // Update progress\n      await updateBatchProgress(metadata.batchId, file.key);\n      \n      return { batchProcessed: true };\n    })\n);\n```\n\n## 🔌 Integration Examples\n\n### Express.js\nSee `examples/express-app.ts` for a complete Express.js integration.\n\n### Next.js\nSee `examples/nextjs-app.ts` for a complete Next.js integration.\n\n### Fastify\n```typescript\nimport fastify from 'fastify';\nimport { createUploadMiddleware } from '@carcosa/file-router';\n\nconst app = fastify();\nconst uploadMiddleware = createUploadMiddleware(uploadRouter);\n\napp.post('/upload/init', async (request, reply) => {\n  return uploadMiddleware.handleUploadInit(request, reply);\n});\n```\n\n## 🆚 vs UploadThing\n\n| Feature | UploadThing | Carcosa File Router |\n|---------|-------------|---------------------|\n| **Typed Routes** | ✅ | ✅ |\n| **Middleware** | ✅ | ✅ |\n| **File Constraints** | ✅ | ✅ |\n| **Upload Callbacks** | ✅ | ✅ |\n| **Storage Control** | ❌ | ✅ (Your buckets) |\n| **Cost Control** | ❌ | ✅ (Your pricing) |\n| **Self-Hosted** | ❌ | ✅ |\n| **Multi-Tenant** | ❌ | ✅ |\n\n## 🚧 Roadmap\n\n- [ ] **Webhook System** - Real-time upload notifications\n- [ ] **Resumable Uploads** - HTTP Range support\n- [ ] **Progress Tracking** - Real-time upload progress\n- [ ] **Transform Pipeline** - Image/video processing\n- [ ] **CDN Integration** - Global file distribution\n- [ ] **Framework Adapters** - Vue, Svelte, React Native\n\n## 🤝 Contributing\n\nWe welcome contributions! Please see our contributing guidelines for more details.\n\n## 📄 License\n\nMIT License - see LICENSE file for details.\n\n---\n\n**Built with ❤️ by the Carcosa Team**\n\n*The UploadThing Killer - Because you deserve better file management! 🚀*","readmeFilename":"README.md","_rev":"1-7c2ea8b3cd7678c9c50f9f5809dabb01"}