From 9bf6e6126053c4383f09ac93bf3e1c643bd6ad18 Mon Sep 17 00:00:00 2001 From: Richard Girges Date: Mon, 28 Aug 2017 10:00:23 -0700 Subject: [PATCH] Updated lib/index.js to be lint-happy. Added promise-based API for `.mv` method. This fixes #42 --- lib/index.js | 77 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 22 deletions(-) diff --git a/lib/index.js b/lib/index.js index eaa531c..f2b2956 100644 --- a/lib/index.js +++ b/lib/index.js @@ -14,8 +14,9 @@ module.exports = function(options) { options = options || {}; return function(req, res, next) { - if (!hasBody(req) || !hasAcceptableMethod(req) || !hasAcceptableMime(req)) + if (!hasBody(req) || !hasAcceptableMethod(req) || !hasAcceptableMime(req)) { return next(); + } processMultipart(options, req, res, next); }; @@ -56,11 +57,13 @@ function processMultipart(options, req, res, next) { let prev = req.body[fieldname]; - if (!prev) + if (!prev) { return req.body[fieldname] = val; + } - if (Array.isArray(prev)) + if (Array.isArray(prev)) { return prev.push(val); + } req.body[fieldname] = [prev, val]; }); @@ -73,34 +76,39 @@ function processMultipart(options, req, res, next) { file.on('data', function(data) { buffers.push(data); - if (options.debug) + if (options.debug) { return console.log('Uploading %s -> %s', fieldname, filename); + } }); file.on('end', function() { - if (!req.files) + if (!req.files) { req.files = {}; + } const buf = Buffer.concat(buffers); // see: https://github.com/richardgirges/express-fileupload/issues/14 // firefox uploads empty file in case of cache miss when f5ing page. // resulting in unexpected behavior. if there is no file data, the file is invalid. - if (!buf.length) + if (!buf.length) { return; + } if (options.safeFileNames) { let maxExtensionLength = 3; let extension = ''; - if (typeof options.safeFileNames === 'object') + if (typeof options.safeFileNames === 'object') { safeFileNameRegex = options.safeFileNames; + } maxExtensionLength = parseInt(options.preserveExtension); if (options.preserveExtension || maxExtensionLength === 0) { - if (isNaN(maxExtensionLength)) + if (isNaN(maxExtensionLength)) { maxExtensionLength = 3; - else + } else { maxExtensionLength = Math.abs(maxExtensionLength); + } let filenameParts = filename.split('.'); let filenamePartsLen = filenameParts.length; @@ -126,20 +134,44 @@ function processMultipart(options, req, res, next) { data: buf, encoding: encoding, mimetype: mime, - mv: function(path, callback) { - let fstream = fs.createWriteStream(path); + mv: function(path, callback = null) { + // Callback is passed in, use the callback API + if (callback) { + doMove( + () => { + callback(null); + }, + (error) => { + callback(error); + } + ); + + // Otherwise, return a promise + } else { + return new Promise((resolve, reject) => { + doMove(resolve, reject); + }); + } - streamifier.createReadStream(buf).pipe(fstream); + /** + * Local function that moves the file to a different location on the filesystem + * Takes two function arguments to make it compatible w/ Promise or Callback APIs + * @param {Function} successFunc + * @param {Function} errorFunc + */ + function doMove(successFunc, errorFunc) { + const fstream = fs.createWriteStream(path); - fstream.on('error', function(error) { - if (callback) - callback(error); - }); + streamifier.createReadStream(buf).pipe(fstream); - fstream.on('close', function() { - if (callback) - callback(null); - }); + fstream.on('error', function(error) { + errorFunc(error); + }); + + fstream.on('close', function() { + successFunc(); + }); + } } }; @@ -148,10 +180,11 @@ function processMultipart(options, req, res, next) { req.files[fieldname] = newFile; } else { // Array fields - if (req.files[fieldname] instanceof Array) + if (req.files[fieldname] instanceof Array) { req.files[fieldname].push(newFile); - else + } else { req.files[fieldname] = [req.files[fieldname], newFile]; + } } });