Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

gulp-awspublish

Package Overview
Dependencies
Maintainers
1
Versions
59
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gulp-awspublish - npm Package Compare versions

Comparing version 0.0.24 to 1.0.0

snippet.js

5

History.md
1.0.0 / 2015-01-29
==================
* refactored to use aws-sdk instead of knox pull request #38 from ronik-design
0.0.24 / 2015-01-06

@@ -3,0 +8,0 @@ ==================

188

lib/index.js

@@ -1,6 +0,4 @@

var Stream = require('stream'),
util = require('util'),
S3Lister = require('s3-lister'),
S3Deleter = require('s3-deleter'),
es = require('event-stream'),
var AWS = require('aws-sdk'),
converter = require('xml-json'),
Stream = require('stream'),
fs = require('fs'),

@@ -10,6 +8,8 @@ through = require('through2'),

crypto = require('crypto'),
knox = require('knox'),
mime = require('mime'),
pascalCase = require('pascal-case'),
gutil = require('gulp-util');
var PLUGIN_NAME = 'gulp-awspublish';
/**

@@ -31,15 +31,78 @@ * calculate file hash

/**
* S3 Error class
* @param {Response} res
* Hunt for appropriate creds
* @param {Options} opts
*
* @return {Credentials} obj
* @api private
*/
function S3Error(res) {
Error.call(this);
this.message = 'HTTP ' + res.statusCode + ' Response returned from S3';
this.res = res;
function getCredentials(opts) {
if (opts && opts instanceof AWS.SharedIniFileCredentials && !opts.accessKeyId) {
return new gutil.PluginError({
plugin: PLUGIN_NAME,
message: 'Bad or invalid credentials'
});
}
// compatibility
if (opts && opts.key && (opts.secret || opts.token)) {
return {
accessKeyId: opts.key,
secretAccessKey: opts.secret,
sessionToken: opts.token
};
}
// When passing to S3, the non-enumerated secretKey won't get copied
if (opts && opts instanceof AWS.SharedIniFileCredentials) {
return {
accessKeyId: opts.accessKeyId,
secretAccessKey: opts.secretAccessKey,
sessionToken: opts.sessionToken
};
}
if (opts && opts.accessKeyId && (opts.secretAccessKey || opts.sessionToken)) {
return {
accessKeyId: opts.accessKeyId,
secretAccessKey: opts.secretAccessKey,
sessionToken: opts.sessionToken
};
}
if (AWS.config.credentials) {
return getCredentials(AWS.config.credentials);
}
return getCredentials(new AWS.SharedIniFileCredentials(opts));
}
util.inherits(S3Error, Error);
/**
* Turn the HTTP style headers into AWS Object params
*/
function toAwsParams(file) {
var params = {};
var headers = file.s3.headers || {};
for (var header in headers) {
if (header === 'x-amz-acl') {
params.ACL = headers[header];
} else {
params[pascalCase(header)] = headers[header];
}
}
params.Key = file.s3.path;
params.Body = file.contents;
return params;
}
module.exports._toAwsParams = toAwsParams;
/**

@@ -62,2 +125,16 @@ * init file s3 hash

function buildDeleteMultiple(keys) {
if (!keys || !keys.length) return;
var deleteObjects = keys.map(function (k) { return { Key: k }; });
return {
Delete: {
Objects: deleteObjects
}
};
}
module.exports._buildDeleteMultiple = buildDeleteMultiple;
/**

@@ -88,3 +165,3 @@ * create a through stream that gzip files

this.emit('error',
new gutil.PluginError('gulp-awspublish', 'Stream content is not supported'));
new gutil.PluginError(PLUGIN_NAME, 'Stream content is not supported'));
return cb();

@@ -139,7 +216,26 @@ }

function Publisher(config) {
var filename = '.awspublish-' + config.bucket;
if (!config.bucket) {
throw new gutil.PluginError({
plugin: PLUGIN_NAME,
message: 'No bucket specified'
});
}
this._bucket = config.bucket;
var filename = '.awspublish-' + this._bucket;
// create client
this.client = knox.createClient(config);
var credentials = getCredentials(config);
if (credentials instanceof Error) {
throw credentials;
}
var s3Opts = credentials;
s3Opts.params = {
Bucket: this._bucket
};
this.client = new AWS.S3(s3Opts);
// load cache

@@ -160,3 +256,3 @@ try {

Publisher.prototype.saveCache = function() {
var filename = '.awspublish-' + this.client.bucket;
var filename = '.awspublish-' + this._bucket;
fs.writeFileSync(filename, JSON.stringify(this._cache));

@@ -240,3 +336,3 @@ };

this.emit('error',
new gutil.PluginError('gulp-awspublish', 'Stream content is not supported'));
new gutil.PluginError(PLUGIN_NAME, 'Stream content is not supported'));
return cb();

@@ -278,11 +374,12 @@ }

// get s3 headers
_this.client.headFile(file.s3.path, function(err, res) {
if (err) return cb(err);
if (res.statusCode !== 200 && res.statusCode !== 307 && res.statusCode !== 404) {
return cb(new S3Error(res));
}
_this.client.headObject({ Key: file.s3.path }, function(err, res) {
if (err && err.statusCode !== 404) return cb(err);
res = res || {};
// skip: no updates allowed
var noUpdate = options.createOnly && res.headers.etag;
var noUpdate = options.createOnly && res.ETag;
// skip: file are identical
var noChange = !options.force && res.headers.etag === etag;
var noChange = !options.force && res.ETag === etag;

@@ -292,3 +389,3 @@ if (noUpdate || noChange) {

file.s3.etag = etag;
file.s3.date = new Date(res.headers['last-modified']);
file.s3.date = new Date(res.LastModified);
cb(err, file);

@@ -298,13 +395,10 @@

} else {
file.s3.state = res.headers.etag
file.s3.state = res.ETag
? 'update'
: 'create';
_this.client.putBuffer(file.contents, file.s3.path, file.s3.headers, function(err, res) {
_this.client.putObject(toAwsParams(file), function(err) {
if (err) return cb(err);
if (res.statusCode !== 200 && res.statusCode !== 307) {
return cb(new S3Error(res));
}
file.s3.date = new Date(res.headers.date);
file.s3.date = new Date();
file.s3.etag = etag;

@@ -342,14 +436,14 @@ cb(err, file);

stream._flush = function(cb) {
var lister = new S3Lister(client, { prefix : prefix }),
deleter = new S3Deleter(client),
filter;
var toDelete = [],
lister;
// filter out newfiles and add deleted file to stream
filter = es.mapSync(function(data) {
var s3path = data.Key;
if (newFiles[s3path]) return;
lister = client.listObjects({ Prefix: prefix })
.createReadStream()
.pipe(converter('Key'));
lister.on('data', function (key) {
if (newFiles[key]) return;
stream.push({
s3: {
path: s3path,
path: key,
state: 'delete',

@@ -359,13 +453,9 @@ headers: {}

});
toDelete.push(key);
});
return data;
lister.on('end', function() {
if (!toDelete.length) return cb();
client.deleteObjects(buildDeleteMultiple(toDelete), cb);
});
lister.on('error', cb);
deleter.on('error', cb);
lister
.pipe(filter)
.pipe(deleter)
.on('finish', cb);
};

@@ -372,0 +462,0 @@

{
"name": "gulp-awspublish",
"version": "0.0.24",
"version": "1.0.0",
"description": "gulp plugin to publish files to amazon s3",

@@ -28,11 +28,10 @@ "keywords": [

"dependencies": {
"through2": "0.x",
"aws-sdk": "^2.1.7",
"clone": "0.x",
"gulp-util": "2.x",
"knox": "0.x",
"mime": "1.x",
"clone": "0.x",
"pad-component": "0.x",
"event-stream": "3.x",
"s3-lister": "0.x",
"s3-deleter": "0.x"
"pascal-case": "^1.1.0",
"through2": "0.x",
"xml-json": "^2.0.2"
},

@@ -43,2 +42,3 @@ "devDependencies": {

"coveralls": "*",
"event-stream": "^3.2.1",
"gulp-rename": "*",

@@ -45,0 +45,0 @@ "istanbul": "*",

@@ -6,9 +6,2 @@ # gulp-awspublish

> **warning** the module does not work currently with node v.0.11.14 see https://github.com/pgherveou/gulp-awspublish/issues/33 for more info
> **warning** users reported a bug in node v.0.10.34 see http://stackoverflow.com/questions/27583347/travis-ci-networkingerror-cert-untrusted-error-between-node-js-and-aws-s3-buck for more info
## Usage

@@ -30,3 +23,3 @@

// create a new publisher
var publisher = awspublish.create({ key: '...', secret: '...', bucket: '...' });
var publisher = awspublish.create({ bucket: '...' });

@@ -63,2 +56,5 @@ // define custom headers

* Note: If you follow the [aws-sdk suggestions](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html) for
providing your credentials you don't need to pass them in to create the publisher.
## Testing

@@ -89,5 +85,9 @@

Create a Publisher.
Options are passed to knox to create a s3 client.
Please see [knox](https://github.com/LearnBoost/knox#client-creation-options) for more details about these options
Options are used to create an `aws-sdk` S3 client. At a minimum you must pass
a `bucket` option, to define the site bucket. If you are using the [aws-sdk suggestions](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html) for credentials you do not need
to provide anything else.
Also supports credentials specified in the old [knox](https://github.com/LearnBoost/knox#client-creation-options)
format, a `profile` property for choosing a specific set of shared AWS creds, or and `accessKeyId` and `secretAccessKey` provided explicitly.
#### Publisher.publish([headers], [options])

@@ -144,3 +144,3 @@

The knox client object exposed to let you do other s3 operations.
The `aws-sdk` S3 client is exposed to let you do other s3 operations.

@@ -147,0 +147,0 @@ ### awspublish.reporter([options])

@@ -25,7 +25,10 @@ /* global describe, before, it */

publisher._cache = {};
publisher.client.deleteMultiple([
var deleteParams = awspublish._buildDeleteMultiple([
'test/hello.txt',
'test/hello2.txt',
'test/hello.txtgz'
], done);
]);
publisher.client.deleteObjects(deleteParams, done);
});

@@ -45,3 +48,3 @@

expect(err).to.be.ok;
expect(err.res.statusCode).to.eq(403);
expect(err.statusCode).to.eq(403);
done();

@@ -59,22 +62,2 @@ });

it('should emit error when user does not have upload rights', function(done) {
var badCredentials = JSON.parse(fs.readFileSync('bad-aws-credentials.json', 'utf8')),
badPublisher = awspublish.create(badCredentials),
stream = badPublisher.publish();
stream.on('error', function(err) {
expect(err).to.be.ok;
expect(err.res.statusCode).to.eq(403);
done();
});
stream.write(new gutil.File({
path: '/test/hello.txt',
base: '/',
contents: new Buffer('hello world 2')
}));
stream.end();
});
it('should produce gzip file with s3 headers', function (done) {

@@ -125,4 +108,4 @@

expect(files).to.have.length(1);
publisher.client.headFile('test/hello.txt.gz', function(err, res) {
expect(res.headers.etag).to.exist;
publisher.client.headObject({ Key: 'test/hello.txt.gz' }, function(err, res) {
expect(res.ETag).to.exist;
done(err);

@@ -164,4 +147,4 @@ });

expect(files[0].s3.headers['Content-Length']).to.eq(files[0].contents.length);
publisher.client.headFile('/test/hello.txt', function(err, res) {
expect(res.headers.etag).to.exist;
publisher.client.headObject({ Key: 'test/hello.txt' }, function(err, res) {
expect(res.ETag).to.exist;
done(err);

@@ -297,5 +280,5 @@ });

expect(files[0].s3.path).to.eq('test/simulate.txt');
publisher.client.headFile('/test/simulate.txt', function(err, res) {
expect(res.statusCode).to.eq(404);
done()
publisher.client.headObject({ Key: '/test/simulate.txt' }, function(err) {
expect(err.statusCode).to.eq(404);
done();
});

@@ -312,7 +295,8 @@ }));

before(function(done) {
publisher.client.deleteMultiple([
var deleteParams = awspublish._buildDeleteMultiple([
'test/hello.txt',
'test/hello2.txt',
'test/hello.txt.gz'
], done);
'test/hello.txtgz'
]);
publisher.client.deleteObjects(deleteParams, done);
});

@@ -322,6 +306,14 @@

['bar', 'foo/1', 'foo/2', 'foo/3'].forEach(function (name) {
var filename = name + '.txt',
headers = {'Content-Type': 'text/plain; charset=utf-8'};
var file = {
s3: {
path: name + '.txt',
headers: {'Content-Type': 'text/plain; charset=utf-8'}
},
contents: new Buffer('hello world')
};
before(function(done) {
publisher.client.putBuffer(name, filename, headers, done);
var params = awspublish._toAwsParams(file);
publisher.client.putObject(params, done);
});

@@ -351,2 +343,2 @@ });

});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc