UNPKG

uploadio

Version:

Simple middleware for uploading files.

133 lines (116 loc) 3.99 kB
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); };