Skip to content

udithavithanage/uploady

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

UPLOADY

A simple but powerful file upload and serving middleware for Node.js/Express.
Supports:

  • File uploads with configurable limits
  • MIME type validation
  • Optional secure URLs with JWT tokens
  • Automatic thumbnail generation for images
  • Organized storage structure (by date)
  • File metadata management
  • Pagination, sorting, and statistics
  • Hooks for upload/delete events

🚀 Installation

npm install uploady multer sharp mime-types jsonwebtoken uuid

📦 Basic Usage

const express = require("express");
const EasyFileServer = require("uploady");

const app = express();

const fileServer = new EasyFileServer({
  storageDir: "./uploads", // where to save files
  maxFileSize: 10 * 1024 * 1024, // 10 MB max
  allowedMimeTypes: ["image/jpeg", "image/png", "application/pdf"],
  organizeByDate: true, // put uploads in YYYY-MM-DD subfolders
  autoThumbnail: true, // generate thumbnails for images
  secureUrls: {
    enabled: true, // use JWT-protected URLs
    expires: 600, // expire in 600 seconds (10 min)
    secret: "super-secret-key", // your JWT secret
  },
});

// Middleware for file uploads
app.post(
  "/upload",
  fileServer.upload("files", 5), // <fieldName>, <maxCount>
  (req, res) => {
    res.json({
      uploaded: req.uploadedFiles,
      errors: req.uploadErrors || [],
    });
  }
);

// Serve uploaded files
app.use("/files", fileServer.serveFiles());

// Serve thumbnails
app.use("/thumbnails", fileServer.serveThumbnails());

// List files (with pagination)
app.get("/list", async (req, res) => {
  const files = await fileServer.listFiles({
    page: Number(req.query.page) || 1,
    limit: 20,
    sortBy: "uploadedAt", // uploadedAt | size | originalName
    sortOrder: "desc", // asc | desc
  });
  res.json(files);
});

// Delete file
app.delete("/delete/:filename", async (req, res) => {
  const success = await fileServer.deleteFile(req.params.filename);
  res.json({ success });
});

// Stats
app.get("/stats", (req, res) => {
  res.json(fileServer.getStats());
});

app.listen(3000, () => {
  console.log("Server running at http://localhost:3000");
});

⚙️ Options

Option Type Default Description
storageDir string ./uploads Where files are stored
maxFileSize number 2GB Max file size in bytes
allowedMimeTypes string[] | null null List of allowed MIME types (null = allow all)
organizeByDate boolean false Organize uploads in YYYY-MM-DD subfolders
autoThumbnail boolean false Generate thumbnails for images
secureUrls.enabled boolean false Enable JWT-protected URLs
secureUrls.expires number 600 (10 minutes) Expiration in seconds
secureUrls.secret string random hex Secret key for signing JWTs

🔒 Secure URLs

When enabled, files and thumbnails are served only with a valid JWT token.

const url = fileServer.generateSecureUrl("file.jpg");
console.log(url);
// -> /files/file.jpg?token=eyJhbGciOi...

To generate thumbnail URLs:

const thumbUrl = fileServer.generateSecureThumbnailUrl("file.jpg");

🖼️ Thumbnails

If autoThumbnail: true, image thumbnails are generated automatically (200x200 max, JPEG).

Thumbnails are accessible at /thumbnails/:filename_thumb.jpg.


📑 API Reference

upload(fieldName, maxCount)

Express middleware for handling file uploads.

  • fieldName – name of form field (default: "files")
  • maxCount – max number of files per request

Result:

  • req.uploadedFiles → array of uploaded metadata
  • req.uploadErrors → array of errors

serveFiles()

Express middleware for serving uploaded files. Supports JWT validation when secureUrls.enabled is true.


serveThumbnails()

Express middleware for serving thumbnails. Also supports JWT validation.


listFiles(options)

Returns a paginated list of file metadata.

Options:

  • page (default: 1)
  • limit (default: 50)
  • sortBy: "uploadedAt", "size", "originalName"
  • sortOrder: "asc" | "desc"

getFileMetadata(filename)

Returns metadata for a single file (excluding internal paths).


deleteFile(filename)

Deletes file and its thumbnail (if exists). Returns true/false.


getStats()

Returns server statistics:

{
  "totalFiles": 12,
  "totalSize": 1048576,
  "totalSizeMB": 1,
  "secureUrlsEnabled": true,
  "storageDir": "/absolute/path/to/uploads"
}

Hooks

Register event hooks with .on(event, fn):

  • onUploadStart(req)
  • onUploadComplete(req, uploadedFiles)
  • onFileDelete(filename, meta)

Example:

fileServer.on("onUploadComplete", (req, uploadedFiles) => {
  console.log("Files uploaded:", uploadedFiles);
});

📤 Example cURL Upload

curl -F "files=@/path/to/image.jpg" http://localhost:3000/upload

Response:

{
  "uploaded": [
    {
      "originalName": "image.jpg",
      "storedName": "1693847392-uuid-image.jpg",
      "mime": "image/jpeg",
      "size": 12345,
      "uploadedAt": "2025-09-07T12:34:56.789Z",
      "url": "/files/1693847392-uuid-image.jpg?token=..."
    }
  ],
  "errors": []
}

🛠️ Notes & Recommendations

  • Use a database instead of in-memory Map in production for metadata persistence.
  • Ensure you set a strong secureUrls.secret in production.
  • Thumbnails are JPEG only (_thumb.jpg).
  • Organize by date if expecting many files (to avoid huge directories).

About

Advanced Express file server with resumable uploads, thumbnails, secure URLs, and metadata management.

Topics

Resources

Stars

Watchers

Forks

Contributors