uploadio
Version:
Simple middleware for uploading files.
133 lines (116 loc) • 3.99 kB
JavaScript
const Busboy = require("busboy");
const { onFileSaveToDisk } = require("./saveToDisk");
var path = require("path");
const { buildOptions, parseFileName, debugLog, buildFields } = require("./utils");
const imageThumbnail = require("image-thumbnail");
const fs = require("fs");
/**
* Processes multipart request
* Builds a req.body object for fields
* Builds a req.files object for files
* @param {Object} options expressFileupload and Busboy options
* @param {Object} req Express request object
* @param {Object} res Express response object
* @param {Function} next Express next method
* @return {void}
*/
module.exports = (options, req, res, next) => {
// Build busboy options and init busboy instance.
const busboyOptions = buildOptions(options, {
headers: req.headers,
});
let files = [];
var busboy = new Busboy(busboyOptions);
// Build multipart req.body fields
busboy.on(
"field",
(field, val) => (req.body = buildFields(req.body, field, val))
);
let fileCounter = 0;
let finished = false;
let uploadLocation = "./uploads";
busboy.on("file", function (fieldname, file, name, encoding, mimetype) {
++fileCounter;
file.fileRead = [];
let ext = name.split(".").pop();
name = name.replace("." + ext, "");
if (options.persistFileName) {
name = name + "." + ext;
} else {
const random = Math.floor(Math.random() * 900000000000000000);
name = random + "." + ext;
}
if (options.uploadDir) {
uploadLocation = options.uploadDir;
}
file.on("data", function (chunk) {
if(options.limits.fileSize) {
fileSize += chunk.length;
if (fileSize >= options.limits.fileSize){
debugLog(options, `limit reached!`);
req.unpipe(busboy);
res.status(500).end('Limit Reached');
}
}
this.fileRead.push(chunk);
});
file.on("error", function (err) {
debugLog(options, `Error while buffering the stream`);
});
file.on("end", async function () {
// Concat the chunks into a Buffer
var finalBuffer = Buffer.concat(this.fileRead);
!fs.existsSync(uploadLocation) &&
fs.mkdirSync(uploadLocation, { recursive: true });
const destination = path.join(uploadLocation, name);
const data = fs.writeFileSync(destination, finalBuffer);
console.log("datadata ", data);
const thumbnailImageUrls = [];
const fileObject = { location: uploadLocation + name, key: name };
if (options.thumbnails) {
debugLog(options, `Generating thumbnails`);
fileObject.thumbnailImageUrls = [];
for (let thumbnail of options.thumbnails) {
let fileOptions = {
width: thumbnail.width || 200,
height: thumbnail.height || 200,
responseType: "buffer",
jpegOptions: {
force: true,
quality,
},
...thumbnail.options
};
const thumbnailImg = await imageThumbnail(finalBuffer, fileOptions);
if (thumbnailImg) {
const fileName = name.replace("." + ext, "");
const thumbnailKey =
fileName +
"_" +
thumbnail.width +
"x" +
thumbnail.height +
"." +
ext;
debugLog(options, `Generating thumbnails to s3`);
const location = path.join(uploadLocation, thumbnailKey);
fs.writeFileSync(location, thumbnailImg);
fileObject.thumbnailImageUrls.push({
[`${thumbnail.width}x${thumbnail.height}`]: location,
});
}
}
}
files.push(fileObject);
if (fileCounter == files.length) {
req.cloudFiles = files;
next();
}
});
});
busboy.on("error", (err) => {
debugLog(options, `Busboy error`);
next(err);
});
req.pipe(busboy);
};