bloody-simple-s3
Advanced tools
Comparing version 0.2.5 to 0.3.0-alpha
@@ -0,1 +1,5 @@ | ||
## 0.3.0-alpha - 2015-03-16 | ||
* Refactor to provide a consistent API | ||
## 0.2.5 - 2015-03-13 | ||
@@ -8,19 +12,19 @@ | ||
* Use #encodeURIComponent() instead of #encodeURI() to encode @CopySource. | ||
* Use #encodeURIComponent() instead of #encodeURI() to encode @CopySource | ||
## 0.2.3 - 2014-11-28 | ||
* Comment test code that wasn't supposed to be there. | ||
* Comment test code that wasn't supposed to be there | ||
## 0.2.2 - 2014-11-28 | ||
* Normalize promise resolve values. | ||
* Normalize promise resolve values | ||
## 0.2.1 - 2014-11-28 | ||
* Allow limit and cursor options on #list(). | ||
* Allow limit and cursor options on #list() | ||
## 0.2.0 - 2014-11-27 | ||
* Introducing #list(), #copy(), #remove(), #move() methods to manipulate files on Amazon S3. | ||
* Old functions refactored with new names and params. | ||
* Introducing #list(), #copy(), #remove(), #move() methods to manipulate files on Amazon S3 | ||
* Old functions refactored with new names and params |
@@ -27,7 +27,7 @@ # Bloody Simple S3 | ||
* `region` _(String)_ optional AWS region; defaults to "us-east-1" | ||
* `sslEnabled` _(String)_ whether to enable SSL for requests | ||
* `sslEnabled` _(Boolean)_ whether to enable SSL for requests | ||
##### Throws | ||
_(Error)_ when options are invalid. | ||
_(Error)_ if options are invalid. | ||
@@ -58,2 +58,6 @@ ##### Example | ||
##### Throws | ||
_(Error)_ if path is invalid. | ||
##### Returns | ||
@@ -82,4 +86,6 @@ | ||
A promise resolving to the attributes of the file that was created/updated. | ||
A promise resolving to the attributes of the created/updated file, i.e. an object with the following properties: | ||
* `path` _(String)_ absolute file path in local filesystem | ||
##### Example | ||
@@ -113,4 +119,8 @@ | ||
A promise resolving to an array of file attributes. | ||
A promise resolving to an array of file attributes, i.e. | ||
* `path` _(String)_ relative file path on S3 | ||
* `size` _(Number)_ file size | ||
* `last_modified` _(Date)_ date file was last modified | ||
##### Example | ||
@@ -122,3 +132,3 @@ | ||
files.forEach(function (file, i) { | ||
console.log(i, file); | ||
console.log(i, file.path); | ||
}); | ||
@@ -143,4 +153,7 @@ }) | ||
A promise resolving to the attributes of the file that was copied. | ||
A promise resolving to the attributes of the file that was copied, i.e. | ||
* `path` _(String)_ relative file path on S3 | ||
* `last_modified` _(Date)_ date file was last modified | ||
##### Example | ||
@@ -222,4 +235,6 @@ | ||
A promise resolving to the (local) path of the downloaded file. | ||
A promise resolving to the attributes of the downloaded file, i.e. an object with the following properties: | ||
* `path` _(String)_ absolute file path on the local filesystem | ||
##### Example | ||
@@ -229,4 +244,4 @@ | ||
s3.download('images/test-123.png', {destination: '/Users/jmike/image.png'}) | ||
.then(function (localPath) { | ||
console.log(localPath); // prints "/Users/jmike/image.png" | ||
.then(function (file) { | ||
console.log(file.path); // prints "/Users/jmike/image.png" | ||
}) | ||
@@ -246,3 +261,3 @@ .catch(function (err) { | ||
* `options` _(Object)_ download options | ||
* `key` _(String)_ destination file path on S3 | ||
* `destination` _(String)_ destination file path on S3 | ||
* `callback` _(Function)_ optional callback function with (err, file) arguments | ||
@@ -252,8 +267,10 @@ | ||
A promise resolving to the attributes of the uploaded file. | ||
A promise resolving to the attributes of the uploaded file, i.e. an object with the followin properties: | ||
* `path` _(String)_ relative file path on S3 | ||
##### Example | ||
```javascript | ||
s3.upload('/Users/jmike/image.png', {key: 'images/jmike.png'}) | ||
s3.upload('/Users/jmike/image.png', {destination: 'images/jmike.png'}) | ||
.then(function (file) { | ||
@@ -260,0 +277,0 @@ // do something on success |
{ | ||
"name": "bloody-simple-s3", | ||
"version": "0.2.5", | ||
"version": "0.3.0-alpha", | ||
"description": "A bloody simple interface to S3, based on the official AWS sdk", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -1,2 +0,2 @@ | ||
var path = require('path'); | ||
var pathjs = require('path'); | ||
var fs = require('fs'); | ||
@@ -9,15 +9,4 @@ var os = require('os'); | ||
/** | ||
* Constructs and returns a new bloody simple S3 client. | ||
* @param {object} options S3 client options. | ||
* @param {string} options.bucket name of the S3 bucket to connect to. | ||
* @param {string} options.accessKeyId your AWS access key ID. | ||
* @param {string} options.secretAccessKey your AWS secret access key. | ||
* @param {string} [options.region=us-east-1] AWS region, defaults to us-east-1. | ||
* @param {boolean} [options.sslEnabled=true] whether to enable SSL for requests. | ||
* @throws {Error} if options are invalid. | ||
* @constructor | ||
*/ | ||
function BloodySimpleS3(options) { | ||
// make sure options is valid | ||
if (!_.isPlainObject(options)) { | ||
@@ -33,36 +22,20 @@ throw new Error('Invalid options param; expected object, received ' + typeof(options)); | ||
// make sure individual options are valid | ||
if (!_.isString(options.bucket)) { | ||
throw new Error( | ||
'Invalid S3 bucket option; ' + | ||
'expected string, received ' + typeof(options.bucket) | ||
); | ||
throw new Error('Invalid bucket option; expected string, received ' + typeof(options.bucket)); | ||
} | ||
if (!_.isString(options.accessKeyId)) { | ||
throw new Error( | ||
'Invalid accessKeyId option; ' + | ||
'expected string, received ' + typeof(options.accessKeyId) | ||
); | ||
throw new Error('Invalid accessKeyId option; expected string, received ' + typeof(options.accessKeyId)); | ||
} | ||
if (!_.isString(options.secretAccessKey)) { | ||
throw new Error( | ||
'Invalid secretAccessKey option; ' + | ||
'expected string, received ' + typeof(options.secretAccessKey) | ||
); | ||
throw new Error('Invalid secretAccessKey option; expected string, received ' + typeof(options.secretAccessKey)); | ||
} | ||
if (!_.isString(options.region)) { | ||
throw new Error( | ||
'Invalid region option; ' + | ||
'expected string, received ' + typeof(options.region) | ||
); | ||
throw new Error('Invalid region option; expected string, received ' + typeof(options.region)); | ||
} | ||
if (!_.isBoolean(options.sslEnabled)) { | ||
throw new Error( | ||
'Invalid sslEnabled option; ' + | ||
'expected boolean, received ' + typeof(options.sslEnabled) | ||
); | ||
throw new Error('Invalid sslEnabled option; expected boolean, received ' + typeof(options.sslEnabled)); | ||
} | ||
@@ -80,21 +53,12 @@ | ||
/** | ||
* Creates and returns a readable stream to the designated file on S3. | ||
* @param {string} key relative path within the S3 bucket. | ||
* @return {ReadableStream} | ||
* @throws {Error} if key is invalid. | ||
*/ | ||
BloodySimpleS3.prototype.createReadStream = function (key) { | ||
BloodySimpleS3.prototype.createReadStream = function (path) { | ||
var params; | ||
// make sure key is valid | ||
if (!_.isString(key)) { | ||
throw new Error( | ||
'Invalid key param; ' + | ||
'expected string, received ' + typeof(key) | ||
); | ||
if (!_.isString(path)) { | ||
throw new Error('Invalid path param; expected string, received ' + typeof(path)); | ||
} | ||
params = { | ||
Key: key, | ||
Key: path, | ||
Bucket: this.bucket | ||
@@ -106,37 +70,25 @@ }; | ||
/** | ||
* Downloads the designated file from S3 to local filesystem. | ||
* @param {string} key relative path within the S3 bucket. | ||
* @param {object} [options] request options. | ||
* @param {string} [options.destination=os.tmpdir()] destination path, i.e. a folder or file. | ||
* @param {function} [callback] optional callback function, i.e. function(err, path). | ||
* @return {Promise} | ||
*/ | ||
BloodySimpleS3.prototype.download = function (key, options, callback) { | ||
BloodySimpleS3.prototype.download = function (path, options, callback) { | ||
var _this = this; | ||
var resolver; | ||
// make sure key param is valid | ||
if (!_.isString(key)) { | ||
return Promise.reject(new Error( | ||
'Invalid key param; ' + | ||
'expected string, received ' + typeof(key) | ||
)).nodeify(callback); | ||
if (!_.isString(path)) { | ||
return Promise.reject(new Error('Invalid path param; expected string, received ' + typeof(path))) | ||
.nodeify(callback); | ||
} | ||
// handle optional params | ||
if (!_.isPlainObject(options)) { | ||
if (_.isFunction(options)) { | ||
callback = options; | ||
} else if (!_.isUndefined(options)) { | ||
return Promise.reject(new Error( | ||
'Invalid options param; ' + | ||
'expected object, received ' + typeof(options) | ||
)).nodeify(callback); | ||
} | ||
if (_.isFunction(options)) { | ||
callback = options; | ||
options = {}; | ||
} else if (_.isUndefined(options)) { | ||
options = {}; | ||
} | ||
// set options defaults | ||
if (!_.isPlainObject(options)) { | ||
return Promise.reject(new Error('Invalid options param; expected object, received ' + typeof(options))) | ||
.nodeify(callback); | ||
} | ||
// set default options | ||
options = _.defaults(options, { | ||
@@ -152,15 +104,13 @@ destination: os.tmpdir() | ||
// make sure destination is either file or folder | ||
if (stats.isDirectory()) { | ||
file = path.join(options.destination, path.basename(key)); | ||
file = pathjs.join(options.destination, pathjs.basename(path)); | ||
} else if (stats.isFile()) { | ||
file = options.destination; | ||
} else { | ||
return reject(new Error( | ||
'Invalid destination path; ' + | ||
'expected folder or file' | ||
)); | ||
return reject(new Error('Invalid destination path; expected folder or file')); | ||
} | ||
readable = _this.createReadStream(key); | ||
readable = _this.createReadStream(path); | ||
writable = fs.createWriteStream(file); | ||
@@ -171,3 +121,5 @@ readable.pipe(writable); | ||
writable.on('finish', function () { | ||
resolve(file); | ||
resolve({ | ||
path: file | ||
}); | ||
}); | ||
@@ -180,10 +132,4 @@ }); | ||
/** | ||
* Creates of updates the designated file on S3, consuming a readable stream. | ||
* @param {string} key relative path within the S3 bucket. | ||
* @param {ReadableStream} readable the readable stream to pull the file data. | ||
* @param {function} [callback] optional callback function, i.e. function(err, data). | ||
* @return {Promise} | ||
*/ | ||
BloodySimpleS3.prototype.writeFileStream = function (key, readable, callback) { | ||
BloodySimpleS3.prototype.writeFileStream = function (path, readable, callback) { | ||
var _this = this; | ||
@@ -193,20 +139,14 @@ var params; | ||
// make sure key param is valid | ||
if (!_.isString(key)) { | ||
return Promise.reject(new Error( | ||
'Invalid key param; ' + | ||
'expected string, received ' + typeof(key) | ||
)).nodeify(callback); | ||
if (!_.isString(path)) { | ||
return Promise.reject(new Error('Invalid path param; expected string, received ' + typeof(path))) | ||
.nodeify(callback); | ||
} | ||
// make sure readable param is valid | ||
if (!(readable instanceof stream.Readable)) { | ||
return Promise.reject(new Error( | ||
'Invalid readable param; ' + | ||
'expected a ReadableStream instance, received ' + typeof(readable) | ||
)).nodeify(callback); | ||
return Promise.reject(new Error('Invalid readable param; expected ReadableStream, received ' + typeof(readable))) | ||
.nodeify(callback); | ||
} | ||
params = { | ||
Key: key, | ||
Key: path, | ||
Body: readable, | ||
@@ -219,3 +159,6 @@ Bucket: _this.bucket | ||
if (err) return reject(err); | ||
resolve({key: key}); | ||
resolve({ | ||
path: path | ||
}); | ||
}); | ||
@@ -227,46 +170,34 @@ }; | ||
/** | ||
* Uploads the designated file to S3. | ||
* @param {string} file absolute/relative path to file in local disk. | ||
* @param {object} [options] upload options. | ||
* @param {string} [options.key] the file name to store in S3. | ||
* @param {function} [callback] optional callback function, i.e. function(err, data). | ||
* @return {Promise} | ||
*/ | ||
BloodySimpleS3.prototype.upload = function (file, options, callback) { | ||
BloodySimpleS3.prototype.upload = function (path, options, callback) { | ||
var _this = this; | ||
var resolver; | ||
// make sure file param is valid | ||
if (!_.isString(file)) { | ||
return Promise.reject(new Error( | ||
'Invalid file param; ' + | ||
'expected string, received ' + typeof(file) | ||
)).nodeify(callback); | ||
if (!_.isString(path)) { | ||
return Promise.reject(new Error('Invalid path param; expected string, received ' + typeof(path))) | ||
.nodeify(callback); | ||
} | ||
// handle optional params | ||
if (!_.isPlainObject(options)) { | ||
if (_.isFunction(options)) { | ||
callback = options; | ||
} else if (!_.isUndefined(options)) { | ||
return Promise.reject(new Error( | ||
'Invalid options param; ' + | ||
'expected object, received ' + typeof(options) | ||
)).nodeify(callback); | ||
} | ||
if (_.isFunction(options)) { | ||
callback = options; | ||
options = {}; | ||
} else if (_.isUndefined(options)) { | ||
options = {}; | ||
} | ||
// resolve relative file | ||
file = path.resolve(__dirname, file); | ||
if (!_.isPlainObject(options)) { | ||
return Promise.reject(new Error('Invalid options param; expected object, received ' + typeof(options))) | ||
.nodeify(callback); | ||
} | ||
// set default values of options | ||
// resolve (possible) relative path | ||
path = pathjs.resolve(__dirname, path); | ||
// set default options | ||
options = _.defaults(options, { | ||
key: path.basename(file) | ||
destination: pathjs.basename(path) | ||
}); | ||
resolver = function(resolve, reject) { | ||
fs.stat(file, function (err, stats) { | ||
fs.stat(path, function (err, stats) { | ||
var readable; | ||
@@ -276,13 +207,9 @@ | ||
// make sure file is referencing a file | ||
if (!stats.isFile()) { | ||
return reject(new Error( | ||
'File path is invalid; ' + | ||
'you need to reference an actual file' | ||
)); | ||
return reject(new Error('File path is invalid; you must reference an actual file')); | ||
} | ||
readable = fs.createReadStream(file); | ||
readable = fs.createReadStream(path); | ||
resolve(_this.writeFileStream(options.key, readable)); | ||
resolve(_this.writeFileStream(options.destination, readable)); | ||
}); | ||
@@ -294,11 +221,3 @@ }; | ||
/** | ||
* Returns an array of (up to 1000) files in the designated directory. | ||
* @param {string} dir relative directory path within the S3 bucket. | ||
* @param {object} [options] list options. | ||
* @param {string} [options.cursor] the key to start with listing files. | ||
* @param {number} [options.limit] maximum number of files to list, must not exceed 1000. | ||
* @param {function} [callback] optional callback function, i.e. function(err, data). | ||
* @return {Promise} | ||
*/ | ||
BloodySimpleS3.prototype.list = function (dir, options, callback) { | ||
@@ -309,27 +228,22 @@ var _this = this; | ||
// make sure dir param is valid | ||
if (!_.isString(dir)) { | ||
return Promise.reject(new Error( | ||
'Invalid dir param; ' + | ||
'expected string, received ' + typeof(dir) | ||
)).nodeify(callback); | ||
return Promise.reject(new Error('Invalid dir param; expected string, received ' + typeof(dir))) | ||
.nodeify(callback); | ||
} | ||
// handle options param | ||
if (!_.isPlainObject(options)) { | ||
if (_.isFunction(options)) { | ||
callback = options; | ||
} else if (!_.isUndefined(options)) { | ||
return Promise.reject(new Error( | ||
'Invalid options param; ' + | ||
'expected object, received ' + typeof(options) | ||
)).nodeify(callback); | ||
} | ||
if (_.isFunction(options)) { | ||
callback = options; | ||
options = {}; | ||
} else if (_.isUndefined(options)) { | ||
options = {}; | ||
} | ||
if (!_.isPlainObject(options)) { | ||
return Promise.reject(new Error('Invalid options param; expected object, received ' + typeof(options))) | ||
.nodeify(callback); | ||
} | ||
params = { | ||
Bucket: this.bucket, | ||
Prefix: path.normalize(dir), | ||
Prefix: pathjs.normalize(dir), | ||
Marker: options.cursor, | ||
@@ -347,5 +261,6 @@ MaxKeys: options.limit | ||
return { | ||
key: obj.Key, | ||
key: obj.Key, // legacy | ||
path: obj.Key, | ||
size: obj.Size, | ||
lastModified: obj.LastModified | ||
last_modified: obj.LastModified | ||
}; | ||
@@ -361,10 +276,3 @@ }); | ||
/** | ||
* Creates a copy of a file that is already stored in Amazon S3. | ||
* @param {string} source relative path of the source file within the S3 bucket. | ||
* @param {string} destination relative path of the copy within the S3 bucket. | ||
* @param {object} [options] copy options. | ||
* @param {function} [callback] optional callback function, i.e. function(err, data). | ||
* @return {Promise} | ||
*/ | ||
BloodySimpleS3.prototype.copy = function (source, destination, options, callback) { | ||
@@ -375,31 +283,27 @@ var _this = this; | ||
// make sure source param is valid | ||
if (!_.isString(source)) return Promise.reject(new Error( | ||
'Invalid source param; ' + | ||
'expected string, received ' + typeof(source) | ||
)).nodeify(callback); | ||
if (!_.isString(source)) { | ||
return Promise.reject(new Error('Invalid source param; expected string, received ' + typeof(source))) | ||
.nodeify(callback); | ||
} | ||
// make sure destination param is valid | ||
if (!_.isString(destination)) return Promise.reject(new Error( | ||
'Invalid destination param; ' + | ||
'expected string, received ' + typeof(destination) | ||
)).nodeify(callback); | ||
if (!_.isString(destination)) { | ||
return Promise.reject(new Error('Invalid destination param; expected string, received ' + typeof(destination))) | ||
.nodeify(callback); | ||
} | ||
// handle options param | ||
if (!_.isPlainObject(options)) { | ||
if (_.isFunction(options)) { | ||
callback = options; | ||
} else if (!_.isUndefined(options)) { | ||
return Promise.reject(new Error( | ||
'Invalid options param; ' + | ||
'expected object, received ' + typeof(options) | ||
)).nodeify(callback); | ||
} | ||
if (_.isFunction(options)) { | ||
callback = options; | ||
options = {}; | ||
} else if (_.isUndefined(options)) { | ||
options = {}; | ||
} | ||
if (!_.isPlainObject(options)) { | ||
return Promise.reject(new Error('Invalid options param; expected object, received ' + typeof(options))) | ||
.nodeify(callback); | ||
} | ||
params = _.assign(options, { | ||
Bucket: this.bucket, | ||
CopySource: encodeURIComponent(path.join(this.bucket, source)), | ||
CopySource: encodeURIComponent(pathjs.join(this.bucket, source)), | ||
Key: destination, | ||
@@ -412,5 +316,7 @@ MetadataDirective: 'COPY' | ||
if (err) return reject(err); | ||
resolve({ | ||
key: destination, | ||
lastModified: data.LastModified | ||
path: destination, | ||
last_modified: data.LastModified | ||
}); | ||
@@ -423,10 +329,4 @@ }); | ||
/** | ||
* Removes the designated file from Amazon S3. | ||
* @param {string} key relative path within the S3 bucket. | ||
* @param {object} [options] remove options. | ||
* @param {function} [callback] optional callback function, i.e. function(err). | ||
* @return {Promise} | ||
*/ | ||
BloodySimpleS3.prototype.remove = function (key, callback) { | ||
BloodySimpleS3.prototype.remove = function (path, callback) { | ||
var _this = this; | ||
@@ -436,11 +336,10 @@ var params; | ||
// make sure key param is valid | ||
if (!_.isString(key)) return Promise.reject(new Error( | ||
'Invalid key param; ' + | ||
'expected string, received ' + typeof(key) | ||
)).nodeify(callback); | ||
if (!_.isString(path)) { | ||
return Promise.reject(new Error('Invalid path param; expected string, received ' + typeof(path))) | ||
.nodeify(callback); | ||
} | ||
params = { | ||
Bucket: this.bucket, | ||
Key: key | ||
Key: path | ||
}; | ||
@@ -458,12 +357,10 @@ | ||
/** | ||
* Moves/renames a file in Amazon S3. | ||
* @param {string} source relative path of the source file within the S3 bucket. | ||
* @param {string} destination relative path of the copy within the S3 bucket. | ||
* @param {object} [options] move options (similar to copy options). | ||
* @param {function} [callback] optional callback function, i.e. function(err, data). | ||
* @return {Promise} | ||
*/ | ||
BloodySimpleS3.prototype.move = function (source, destination, options, callback) { | ||
return this.copy(source, destination) | ||
if (_.isFunction(options)) { | ||
callback = options; | ||
options = {}; | ||
} | ||
return this.copy(source, destination, options) | ||
.bind(this) | ||
@@ -476,36 +373,3 @@ .then(function (data) { | ||
module.exports = BloodySimpleS3; | ||
// require('dotenv').load(); | ||
// var s3 = new BloodySimpleS3({ | ||
// bucket: 'sdk-analytics', | ||
// accessKeyId: process.env.AWS_ACCESS_KEY_ID, | ||
// secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, | ||
// sslEnabled: true | ||
// }); | ||
// s3.list('./temp') | ||
// .then(function (arr) { | ||
// console.log(arr); | ||
// return s3.copy('temp/A+ Manga 1.0.ipa', 'temp/0a') | ||
// .then(function (data) { | ||
// console.log(data); | ||
// // return s3.remove('temp/0a'); | ||
// }) | ||
// .catch(function (data) { | ||
// console.log(data); | ||
// }); | ||
// }) | ||
// .catch(function (err) { | ||
// console.error(err); | ||
// }); | ||
// s3.upload({ | ||
// source: path.resolve(__dirname, '../LICENSE'), | ||
// key: 'apk/test' | ||
// }).then(function (data) { | ||
// console.log(data); | ||
// }).catch(function (err) { | ||
// console.error(err); | ||
// }); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19729
307