Skip to content

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

Notifications You must be signed in to change notification settings

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