Transform upload with NodeJS Multer
Not sure if you're still looking for an answer to this, but I had the same problem. I decided to extend the multer-s3
package.
I've opened a pull request to the original repository, but for now, you can use my fork.
Here's an example of how to use the extended version:
var upload = multer({ storage: multerS3({ s3: s3, bucket: 'some-bucket', shouldTransform: function (req, file, cb) { cb(null, /^image/i.test(file.mimetype)) }, transforms: [{ id: 'original', key: function (req, file, cb) { cb(null, 'image-original.jpg') }, transform: function (req, file, cb) { cb(null, sharp().jpg()) } }, { id: 'thumbnail', key: function (req, file, cb) { cb(null, 'image-thumbnail.jpg') }, transform: function (req, file, cb) { cb(null, sharp().resize(100, 100).jpg()) } }] }) })
EDIT: My fork is also now available via npm under the name multer-s3-transform
.
I've tried using @ItsGreg's fork, but couldn't get it to work. I managed to get this behaviour working by using multer-s3 standard configuration, and inside my file upload endpoint, i.e.,
app.post('/files/upload', upload.single('file'), (req, res) => {...})
I am retrieving the file using request, and passing the Buffer to sharp. The following works (and assumes you are using ~/.aws/credentials
):
let request = require('request').defaults({ encoding: null }); let dataURI = `https://s3.amazonaws.com/${process.env.AWS_S3_BUCKET}/${image.defaultUrl}`; request.get(dataURI, function (error, response, body) { if (! error && response.statusCode === 200) { let buffer = new Buffer(body); const sizes = ['thumbnail', 'medium', 'large']; sizes.forEach(size => { sharp(buffer) .resize(image.sizes[size]) .toBuffer() .then(data => { // Upload the resized image Buffer to AWS S3. let params = { Body: data, Bucket: process.env.AWS_S3_BUCKET, Key: `${image.filePath}${image.names[size]}`, ServerSideEncryption: "AES256", }; s3.putObject(params, (err, data) => { if (err) console.log(err, err.stack); // an error occurred else console.log(data); // successful response }); }) }) } });