From 447caae216e8f49d2b6b334a6bcc97aae4061769 Mon Sep 17 00:00:00 2001 From: Chih Hung Chen Date: Thu, 23 Nov 2017 14:20:44 +0800 Subject: [PATCH] fix(files): update files.upload format to support kloudless v1 api feat(files): support fs.ReadStream file type fix(files): fix incorrect grammar --- lib/methods/files.js | 35 ++++++++++++++++++++++++++++------- lib/resources.js | 28 +++++++++++++--------------- lib/utils.js | 18 ++++++++++++++++++ 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/lib/methods/files.js b/lib/methods/files.js index 4c9b99e..4b6106d 100644 --- a/lib/methods/files.js +++ b/lib/methods/files.js @@ -1,6 +1,7 @@ var BaseMethod = require('./basemethod'); var fs = require('fs'); var Error = require('../error'); +var utils = require('../utils'); var FilesMethods = { upload: BaseMethod.extend({ @@ -13,15 +14,35 @@ var FilesMethods = { 'file' ], dataFunction: function(data, cb) { - if (data['file'] instanceof fs.ReadStream || data['file'] instanceof Buffer) { + if (data['file']) { data['metadata'] = JSON.stringify({'parent_id': data['parent_id'], 'name': data['name']}); - cb(null, data); - } else { - cb(new Error.KloudlessError( - {message: "The 'file' parameter for files.upload()"+ - " must be an instance of either Buffer or fs.ReadStream."} - )); + + if (data['file'] instanceof Buffer) { + cb(null, data); + } else if (data['file'] instanceof fs.ReadStream) { + //convert fs.ReadStream to Buffer + utils.streamToBuffer(data['file']) + .then(function (fileBuffer) { + data['file'] = fileBuffer; + cb(null, data); + }) + .catch(function () { + cb(new Error.KloudlessError( + { + message: "Failed to convert ReadStream to Buffer." + } + )); + }); + } else { + cb(new Error.KloudlessError( + { + message: "The 'file' parameter for files.upload()" + + " must be an instance of either Buffer." + } + )); + } } + } }), get: BaseMethod.extend({ diff --git a/lib/resources.js b/lib/resources.js index 3ae53c0..8a1c2dd 100644 --- a/lib/resources.js +++ b/lib/resources.js @@ -114,20 +114,18 @@ BaseResource.prototype = { user_headers = user_headers || {}; var headers; var requestData = JSON.stringify(data || {}); - var requestForm = new FormData(); - var shouldPipeForm = false; - - if (data['file'] && (data['file'] instanceof Buffer)) { - shouldPipeForm = true; - for (var dataName in data) { - var appendData = data[dataName]; - if(dataName != "queryParams") { - if(dataName == "file" && data['name']) requestForm.append(dataName, appendData, {filename: data['name']}); - else requestForm.append(dataName, appendData); - } + var shouldPipeFile = false; + + if (data['file'] && (data['file'] instanceof Buffer || data['file'] instanceof fs.ReadStream)) { + shouldPipeFile = true; + + headers = { + 'Authorization': this._kloudless.getApiField('auth'), + 'Accept': 'application/json', + 'Content-Type': "application/octet-stream", + 'X-Kloudless-Metadata': data['metadata'] + // X-Kloudless-Metadata is json like '{"name": "hello.png", "parent_id": "fL2hp"}' } - headers = requestForm.getHeaders(); - headers['Authorization'] = this._kloudless.getApiField('auth'); } else { headers = { 'Authorization': this._kloudless.getApiField('auth'), @@ -166,8 +164,8 @@ BaseResource.prototype = { req.on('response', self._responseHandler(req, parseResponse, callback)); req.on('error', self._errorHandler(req, callback)); - if (shouldPipeForm) { - requestForm.pipe(req); + if (shouldPipeFile) { + req.write(data['file']); } else { req.write(requestData, 'utf8'); } diff --git a/lib/utils.js b/lib/utils.js index 473e3d5..5360f36 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -22,5 +22,23 @@ var utils = module.exports = { } } return Constructor; + }, + /** + * convert fs.ReadStream to Buffer + * + * @param {fs.ReadStream} stream + * @returns {Promise} + */ + streamToBuffer: function (stream) { + return new Promise(function (resolve, reject) { + var buffers = []; + stream.on('error', reject); + stream.on('data', function (data) { + return buffers.push(data); + }); + stream.on('end', function () { + return resolve(Buffer.concat(buffers)); + }); + }) } };