diff --git a/index.js b/index.js index b4a475a..357aa91 100644 --- a/index.js +++ b/index.js @@ -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 @@ -17,8 +18,6 @@ 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; } @@ -26,12 +25,13 @@ function S3BlobStore (opts) { /** * 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); @@ -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|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 */ @@ -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); @@ -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|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|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 */ @@ -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 + */ diff --git a/readme.md b/readme.md index 750a15c..dd906ec 100644 --- a/readme.md +++ b/readme.md @@ -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 @@ -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 @@ -95,7 +98,7 @@ Create write stream ##### Parameters - `opts` **([Options](#options)<[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 @@ -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)<[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 @@ -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)<[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: ** - -S3 `putObject` params - -### Options +### -Type: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) +### ExistsParams -#### Properties +- **See: ** -- `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 @@ -155,4 +151,25 @@ S3 client S3 `getObject` params -### +### WriteParams + +- **See: ** + +S3 `putObject` params + +### RemoveParams + +- **See: ** + +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