Skip to content

Refactor and docs #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 64 additions & 39 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var downloader = require('s3-download-stream');
var debug = require('debug')('s3-blob-store');
var mime = require('mime-types');
var uploadStream = require('s3-stream-upload');
var util = require('util');

/**
* Create S3 blob store
Expand All @@ -17,21 +18,20 @@ function S3BlobStore (opts) {
opts = opts || {};
if (!opts.client) throw Error('S3BlobStore client option required (aws-sdk AWS.S3 instance)');
if (!opts.bucket) throw Error('S3BlobStore bucket option required');
this.accessKey = opts.accessKey;
this.secretKey = opts.secretKey;
this.bucket = opts.bucket;
this.s3 = opts.client;
}

/**
* Create read stream
* @param {ReadStreamOptions|String} opts options or object key
* @param {ReadParams} [s3opts] additional S3 options
* @returns {ReadableStream}
* readable stream of data for the file in your bucket whose key matches
*/
S3BlobStore.prototype.createReadStream = function (opts) {
S3BlobStore.prototype.createReadStream = function (opts, s3opts) {
if (typeof opts === 'string') opts = { key: opts };
var config = { client: this.s3, params: this.downloadParams(opts) };
var config = { client: this.s3, params: this._s3params(opts, s3opts) };
if (opts.concurrency) config.concurrency = opts.concurrency;
if (opts.chunkSize) config.chunkSize = opts.chunkSize;
var stream = downloader(config);
Expand All @@ -41,36 +41,10 @@ S3BlobStore.prototype.createReadStream = function (opts) {
return stream;
};

S3BlobStore.prototype.uploadParams = function (opts) {
opts = Object.assign({}, opts, {
params: Object.assign({}, opts.params)
});

var filename = opts.name || opts.filename;
var key = opts.key || filename;
var contentType = opts.contentType;

var params = opts.params;
params.Bucket = params.Bucket || this.bucket;
params.Key = params.Key || key;

if (!contentType) {
contentType = filename ? mime.lookup(filename) : mime.lookup(opts.key);
}
if (contentType) params.ContentType = contentType;

return params;
};

S3BlobStore.prototype.downloadParams = function (opts) {
var params = this.uploadParams(opts);
delete params.ContentType;
return params;
};

/**
* Create write stream
* @param {Options<WriteParams>|String} opts options or object key
* @param {WriteParams} [s3opts] additional S3 options
* @param {function(Error, { key: String })} done callback
* @returns {WritableStream} writable stream that you can pipe data to
*/
Expand All @@ -80,7 +54,9 @@ S3BlobStore.prototype.createWriteStream = function (opts, s3opts, done) {
s3opts = {};
}
if (typeof opts === 'string') opts = { key: opts };
var params = this.uploadParams(opts);
var params = this._s3params(opts, s3opts);
var contentType = (opts && opts.contentType) || mime.lookup(params.Key);
if (contentType) params.ContentType = contentType;
var out = uploadStream(this.s3, params);
out.on('error', function (err) {
debug('got err %j', err);
Expand All @@ -95,28 +71,63 @@ S3BlobStore.prototype.createWriteStream = function (opts, s3opts, done) {

/**
* Remove object from store
* @param {{ key: String }|String} opts options containing object key or just key
* @param {Options<RemoveParams>|String} opts options or object key
* @param {RemoveParams} [s3opts] additional S3 options
* @param {function(Error)} done callback
*/
S3BlobStore.prototype.remove = function (opts, done) {
var key = typeof opts === 'string' ? opts : opts.key;
this.s3.deleteObject({ Bucket: this.bucket, Key: key }, done);
S3BlobStore.prototype.remove = function (opts, s3opts, done) {
if (typeof s3opts === 'function') {
done = s3opts;
s3opts = {};
}
if (typeof opts === 'string') opts = { key: opts };
var params = this._s3params(opts, s3opts);
this.s3.deleteObject(params, done);
return this;
};

/**
* Check if object exits
* @param {{ key: String }|String} opts options containing object key or just key
* @param {Options<ExistsParams>|String} opts options or object key
* @param {ExistsParams} [s3opts] additional S3 options
* @param {function(Error, Boolean)} done callback
*/
S3BlobStore.prototype.exists = function (opts, done) {
S3BlobStore.prototype.exists = function (opts, s3opts, done) {
if (typeof s3opts === 'function') {
done = s3opts;
s3opts = {};
}
if (typeof opts === 'string') opts = { key: opts };
this.s3.headObject({ Bucket: this.bucket, Key: opts.key }, function (err, res) {
var params = this._s3params(opts, s3opts);
this.s3.headObject(params, function (err, _res) {
if (err && err.statusCode === 404) return done(null, false);
done(err, !err);
});
};

S3BlobStore.prototype._s3params = function (opts, s3opts) {
opts = opts || {};
opts.params = s3opts || opts.params || {};
var key = opts.key || opts.name || opts.filename;
var params = Object.assign({}, opts.params, {
Bucket: opts.params.Bucket || this.bucket,
Key: opts.params.Key || key
});
return params;
};

S3BlobStore.prototype.uploadParams = util.deprecate(function (opts) {
opts = opts || {};
var params = this._s3params(opts);
var contentType = opts.contentType || mime.lookup(params.Key);
if (contentType) params.ContentType = contentType;
return params;
}, 'S3BlobStore#uploadParams(opts) is deprecated and will be removed in upcoming v5!');

S3BlobStore.prototype.downloadParams = util.deprecate(function (opts) {
return this._s3params(opts);
}, 'S3BlobStore#downloadParams(opts) is deprecated and will be removed in upcoming v5!');

module.exports = S3BlobStore;

/** @typedef {import('stream').Readable} ReadableStream */
Expand Down Expand Up @@ -158,3 +169,17 @@ module.exports = S3BlobStore;
* @name WriteParams
* @see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property
*/

/**
* S3 `deleteObject` params
* @typedef {import('aws-sdk').S3.DeleteObjectRequest} RemoveParams
* @name RemoveParams
* @see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#deleteObject-property
*/

/**
* S3 `headObject` params
* @typedef {import('aws-sdk').S3.HeadObjectRequest} ExistsParams
* @name ExistsParams
* @see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#headObject-property
*/
57 changes: 37 additions & 20 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,14 @@ store.exists({ key: 'somefile.txt' }, function (err, exists) {
- [Parameters](#parameters-3)
- [exists](#exists)
- [Parameters](#parameters-4)
- [WriteParams](#writeparams)
- [Options](#options)
- [Properties](#properties)
- [ExistsParams](#existsparams)
- [ReadStreamOptions](#readstreamoptions)
- [S3](#s3)
- [ReadParams](#readparams)
- [WriteParams](#writeparams)
- [RemoveParams](#removeparams)
- [Options](#options)
- [Properties](#properties)

### S3BlobStore

Expand All @@ -85,6 +87,7 @@ Create read stream
##### Parameters

- `opts` **([ReadStreamOptions](#readstreamoptions) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** options or object key
- `s3opts` **[ReadParams](#readparams)?** additional S3 options

Returns **ReadableStream** readable stream of data for the file in your bucket whose key matches

Expand All @@ -95,7 +98,7 @@ Create write stream
##### Parameters

- `opts` **([Options](#options)&lt;[WriteParams](#writeparams)> | [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** options or object key
- `s3opts`
- `s3opts` **[WriteParams](#writeparams)?** additional S3 options
- `done` **function ([Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error), {key: [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)})** callback

Returns **WritableStream** writable stream that you can pipe data to
Expand All @@ -106,7 +109,8 @@ Remove object from store

##### Parameters

- `opts` **({key: [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)} | [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** options containing object key or just key
- `opts` **([Options](#options)&lt;[RemoveParams](#removeparams)> | [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** options or object key
- `s3opts` **[RemoveParams](#removeparams)?** additional S3 options
- `done` **function ([Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error))** callback

#### exists
Expand All @@ -115,27 +119,19 @@ Check if object exits

##### Parameters

- `opts` **({key: [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)} | [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** options containing object key or just key
- `opts` **([Options](#options)&lt;[ExistsParams](#existsparams)> | [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** options or object key
- `s3opts` **[ExistsParams](#existsparams)?** additional S3 options
- `done` **function ([Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error), [Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** callback

###

### WriteParams

- **See: <https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property>**

S3 `putObject` params

### Options
###

Type: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)
### ExistsParams

#### Properties
- **See: <https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#headObject-property>**

- `key` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** object key
- `name` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** `key` alias
- `filename` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** `key` alias
- `params` **S3Params?** additional S3 options
S3 `headObject` params

### ReadStreamOptions

Expand All @@ -155,4 +151,25 @@ S3 client

S3 `getObject` params

###
### WriteParams

- **See: <https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property>**

S3 `putObject` params

### RemoveParams

- **See: <https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#deleteObject-property>**

S3 `deleteObject` params

### Options

Type: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)

#### Properties

- `key` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** object key
- `name` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** `key` alias
- `filename` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** `key` alias
- `params` **S3Params?** additional S3 options