Upload
The Upload module provides secure file upload handling with configurable validation for both single and multiple file uploads.
Configuration
Section titled “Configuration”Basic Setup
Section titled “Basic Setup”import { Upload } from "harpiats/upload";
const upload = new Upload({ fieldName: "file", // Form field name for uploads path: "uploads", // Storage directory prefix: "user", // Optional filename prefix fileName: "custom-name", // Optional custom filename options: { maxSize: 5 * 1024 * 1024, // 5MB default allowedExtensions: [".jpg", ".png"], allowedTypes: ["image/jpeg", "image/png"] }});Configuration Options
Section titled “Configuration Options”| Option | Type | Default | Description |
|---|---|---|---|
fieldName | string | "file" | Form field name for file upload |
path | string | "uploads" | Directory to save uploaded files |
prefix | string | undefined | Prefix for uploaded filenames |
fileName | string | undefined | Custom filename (without extension) |
options | object | See below | Validation options |
Validation Options:
maxSize: Maximum file size in bytes (default: 5MB)allowedExtensions: Array of permitted file extensionsallowedTypes: Array of permitted MIME types
Single File Upload
Section titled “Single File Upload”app.post("/avatar", upload.single, async (req, res) => { // File is automatically saved to configured path res.json({ message: "File uploaded successfully" });});Multiple File Upload
Section titled “Multiple File Upload”app.post("/gallery", upload.multiple, async (req, res) => { // All valid files are saved automatically res.json({ message: "Files processed" });});File Naming
Section titled “File Naming”The module generates filenames following these rules:
- If
fileNameis provided:[prefix]-[fileName].[ext] - Otherwise:
[prefix]-[originalName].[ext]
Example with prefix: "user" and original file photo.jpg:
user-photo.jpg(no custom fileName)user-profile.jpg(withfileName: "profile")
Validation
Section titled “Validation”Error Handling
Section titled “Error Handling”The middleware automatically validates files against:
- Size limits
- File extensions
- MIME types
Invalid files trigger 400 responses with detailed error messages:
{ "message": "Some files failed to process", "errors": [ { "fileName": "document.pdf", "message": "The file has a disallowed extension. Allowed extensions: .jpg, .png" } ]}Custom Validation
Section titled “Custom Validation”For additional validation, access the file in your route handler:
app.post("/upload", upload.single, async (req, res) => { const formData = await req.formData(); const file = formData.get("file") as File;
// Custom validation logic if (file.name.includes("admin")) { fs.unlinkSync(path.join(upload.path, file.name)); return res.status(403).json({ error: "Invalid filename" }); }
res.json({ success: true });});API Reference
Section titled “API Reference”Upload Class
Section titled “Upload Class”new Upload(options?: UploadConstructor)
Methods:
.single: Middleware for single file upload.multiple: Middleware for multiple file upload
Internal Methods:
fileChecker: Validates files against configurationcheckMaxSize: Size validationcheckExtensions: Extension validationcheckTypes: MIME type validation
Best Practices
Section titled “Best Practices”-
Security Recommendations:
new Upload({options: {allowedTypes: ["image/jpeg", "image/png"], // Whitelist only safe typesmaxSize: 2 * 1024 * 1024 // Limit to 2MB for images}}); -
Production Setup:
- Store files outside application directory
- Use random filenames for security
fileName: crypto.randomUUID() // Generate random filenames -
Error Recovery:
app.use((err, req, res, next) => {if (err.code === "LIMIT_FILE_SIZE") {res.status(413).json({ error: "File too large" });}// Handle other errors});