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

mailchimp-api-v3

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mailchimp-api-v3 - npm Package Compare versions

Comparing version 1.1.0 to 1.2.0

465

index.js

@@ -6,2 +6,3 @@ "use strict";

zlib = require('zlib'),
Promise = require("bluebird"),
_ = require('lodash');

@@ -48,5 +49,5 @@

Mailchimp.prototype.get = function (options, done) {
options = options || {};
options = _.clone(options)
Mailchimp.prototype.get = function (options, query, done) {
options = _.clone(options) || {};
if (_.isString(options)) {

@@ -58,8 +59,22 @@ options = {

options.method = 'get';
this.request(options, done);
if (!done && _.isFunction(query)) {
done = query;
query = null;
}
if (query && options.query) {
console.warn('query set on request options overwritten by argument query');
}
if (query) {
options.query = query;
}
return this.request(options, done);
}
Mailchimp.prototype.post = function (options, done) {
options = options || {};
options = _.clone(options)
Mailchimp.prototype.post = function (options, body, done) {
options = _.clone(options) || {};
if (_.isString(options)) {

@@ -71,8 +86,22 @@ options = {

options.method = 'post';
this.request(options, done);
if (!done && _.isFunction(body)) {
done = body;
body = null;
}
if (body && options.body) {
console.warn('body set on request options overwritten by argument body');
}
if (body) {
options.body = body;
}
return this.request(options, done);
}
Mailchimp.prototype.patch = function (options, done) {
options = options || {};
options = _.clone(options)
Mailchimp.prototype.patch = function (options, body, done) {
options = _.clone(options) || {};
if (_.isString(options)) {

@@ -84,8 +113,22 @@ options = {

options.method = 'patch';
this.request(options, done);
if (!done && _.isFunction(body)) {
done = body;
body = null;
}
if (body && options.body) {
console.warn('body set on request options overwritten by argument body');
}
if (body) {
options.body = body;
}
return this.request(options, done);
}
Mailchimp.prototype.put = function (options, done) {
options = options || {};
options = _.clone(options)
Mailchimp.prototype.put = function (options, body, done) {
options = _.clone(options) || {};
if (_.isString(options)) {

@@ -97,3 +140,17 @@ options = {

options.method = 'put';
this.request(options, done);
if (!done && _.isFunction(body)) {
done = body;
body = null;
}
if (body && options.body) {
console.warn('body set on request options overwritten by argument body');
}
if (body) {
options.body = body;
}
return this.request(options, done);
}

@@ -110,93 +167,105 @@

options.method = 'delete';
this.request(options, done);
return this.request(options, done);
}
Mailchimp.prototype.getAndUnpackBatchResults = function (response_body_url, done, opts) {
var read = request.get(response_body_url);
Mailchimp.prototype._getAndUnpackBatchResults = function (response_body_url, opts) {
var parse = tar.Parse();
return new Promise(function (resolve, reject) {
var read = request.get(response_body_url);//DELETE?
parse.on('entry', function(entry){
var parse = tar.Parse();
if (!entry.path.match(/\.json/)){
return
}
parse.on('entry', function(entry){
if (!entry.path.match(/\.json/)){
return
}
var result_json = '';
entry.on('data', function (data) {
result_json += data.toString();
})
var result_json = '';
entry.on('data', function (data) {
result_json += data.toString();
})
entry.on('error', function (err) {
parse.close();
entry.close();
done(err);
})
entry.on('error', function (err) {
parse.close();
entry.close();
reject(err);
})
entry.on('end', function () {
var results = JSON.parse(result_json)
entry.on('end', function () {
var results = JSON.parse(result_json)
results.sort(function (result_a, result_b) {
return result_a.operation_id - result_b.operation_id
})
results.sort(function (result_a, result_b) {
return result_a.operation_id - result_b.operation_id
})
for (var i = 0; i < results.length; i++) {
results[i] = JSON.parse(results[i].response);
};
for (var i = 0; i < results.length; i++) {
results[i] = JSON.parse(results[i].response);
};
if (results.length == 1 && opts.unarray) {
results = results[0];
}
resolve(results)
})
});
done(null, results)
parse.on('error', function (err) {
parse.close();
reject(err);
})
parse.on('end', function (res) {
})
});
parse.on('error', function (err) {
parse.close();
done(err);
})
request.get({
url : response_body_url,
encoding : null
}, function (err, response) {
if (err) {
reject(err);
return;
}
parse.on('end', function (res) {
console.log('end', res);
})
if (response.statusCode != 200) {
reject(new String(response.body));
return;
}
var response_buffer = response.body;
request.get({
url : response_body_url,
encoding : null
}, function (err, response) {
if (err) {
done(err);
return;
}
zlib.gunzip(response_buffer, function (err, result) {
if (err) {
reject(err);
return;
}
if (response.statusCode != 200) {
done(new String(response.body));
return;
}
parse.end(result)
var response_buffer = response.body;
})
zlib.gunzip(response_buffer, function (err, result) {
if (err) {
done(err);
return;
}
})
parse.end(result)
})
})
})
}
Mailchimp.prototype.batchWait = function (batch_id, done, opts) {
opts = opts || {};
var mailchimp = this;
//If done is not a function, and no opts are given, second argument is the opts
if (!opts && !_.isFunction(done)) {
opts = done;
done = null;
}
opts = _.clone(opts) || {};
if (!opts.interval) {
opts.interval = 2000
}
//default unpack to true

@@ -207,6 +276,7 @@ if (opts.unpack !== false) {

var _this = this;
//default verbose to true
if (opts.verbose !== false) {
opts.verbose = true;
}
var interval = opts.interval || '2000'
var options = {

@@ -217,43 +287,65 @@ method : 'get',

var promise = new Promise(function (resolve, reject) {
var request = function () {
mailchimp.request(options)
.then(function (result) {
if (opts.verbose) {
console.log('batch status:', result.status, result.finished_operations + '/' + result.total_operations)
}
if (result.status == 'finished') {
resolve(result);
return;
}
if (opts.unpack) {
var _done = done;
var _this = this;
done = function (err, result) {
if (err) {
_done(err);
return;
}
setTimeout(request, opts.interval);
_this.getAndUnpackBatchResults(result.response_body_url, _done, opts)
}, reject)
}
request();
})
if (opts.unpack) {
promise = promise.then(function (result) {
return mailchimp._getAndUnpackBatchResults(result.response_body_url, opts)
})
}
var request = function () {
_this.request(options, function (err, result) {
if (err) {
//If a callback is used, resolve it and don't return the promise
if (done) {
promise
.then(function (result) {
done(null, result)
})
.catch(function (err) {
done(err);
return;
}
})
return;
}
if (opts.verbose !== false) {
console.log('batch status:', result.status, result.finished_operations + '/' + result.total_operations)
}
if (result.status == 'finished') {
done(null, result);
return
}
return promise
}
setTimeout(request, interval)
Mailchimp.prototype.batch = function (operations, done, opts) {
var mailchimp = this;
})
//If done is not a function, and no opts are given, second argument is the opts
if (!opts && !_.isFunction(done)) {
opts = done;
done = null;
}
request();
}
opts = _.clone(opts) || {};
Mailchimp.prototype.batch = function (operations, done, opts) {
opts = opts || {};
//TODO: Validate arguments and reject errors
//If the batch call does not get an operation, but a single normal call, return the result instead of a length 1 array
//This is useful for large get requests, like all subscribers of a list without paging
var should_unarray = false;
if (!_.isArray(operations)) {
operations = [operations]
should_unarray = true;
}
//default wait to true

@@ -264,18 +356,10 @@ if (opts.wait !== false) {

if (!_.isArray(operations)) {
operations = [operations]
opts.unarray = true;
//default unpack to true
if (opts.unpack !== false) {
opts.unpack = true;
}
if (opts.wait) {
var _done = done;
var _this = this;
done = function (err, result) {
if (err) {
_done(err);
return;
}
_this.batchWait(result.id, _done, opts)
}
//default verbose to true
if (opts.verbose !== false) {
opts.verbose = true;
}

@@ -298,3 +382,4 @@

this.request({
var promise = mailchimp.request({
method : 'post',

@@ -305,63 +390,115 @@ path : '/batches',

}
}, done)
})
}
Mailchimp.prototype.request = function (options, done) {
if (!_.isFunction(done)) {
done = function () {}
if (opts.verbose) {
promise = promise.then(function (result) {
console.log('Batch started with id:', result.id);
return result
})
}
if (!options) {
done(new Error("No request options given"));
return;
if (opts.wait) {
promise = promise.then(function (result) {
return mailchimp.batchWait(result.id, opts)
})
}
if (_.isString(options)) {
options = {
path : options,
}
if (opts.wait && opts.unpack && should_unarray) {
promise = promise.then(function (result) {
if (result.length == 1) {
result = result[0];
}
return result
})
}
var path = formatPath(options.path, options.path_params);
var method = options.method || 'get';
var body = options.body || {};
var params = options.params;
var query = options.query;
if (params) {
console.warn('params is depricated, use query instead');
if (!query) {
query = params;
}
}
if (!path || !_.isString(path)) {
done(new Error('No path given'));
//If a callback is used, resolve it and don't return the promise
if (done) {
promise
.then(function (result) {
done(null, result)
})
.catch(function (err) {
done(err);
})
return;
}
request({
method : method,
url : this.__base_url + path,
auth : {
user : 'any',
password : this.__api_key
},
json : body,
qs : query
}, function (err, response) {
if (err) {
done(err);
return promise
}
Mailchimp.prototype.request = function (options, done) {
var mailchimp = this;
var promise = new Promise(function(resolve, reject) {
if (!options) {
reject(new Error("No request options given"));
return;
}
if (response.statusCode != 200) {
console.log(path)
done(response.body);
var path = formatPath(options.path, options.path_params);
var method = options.method || 'get';
var body = options.body || {};
var params = options.params;
var query = options.query;
//Parems used to refer to query parameters, because of the mailchimp documentation.
if (params) {
console.warn('params is depricated, use query instead');
if (!query) {
query = params;
}
}
if (!path || !_.isString(path)) {
reject(new Error('No path given'))
return;
}
request({
method : method,
url : mailchimp.__base_url + path,
auth : {
user : 'any',
password : mailchimp.__api_key
},
json : body,
qs : query,
headers : {
'User-Agent' : 'mailchimp-api-v3 : https://github.com/thorning/node-mailchimp'
}
}, function (err, response) {
done(null, response.body)
if (err) {
reject(err)
return;
}
if (response.statusCode != 200) {
reject(response.body);
return;
}
resolve(response.body)
})
})
//If a callback is used, resolve it and don't return the promise
if (done) {
promise
.then(function (result) {
done(null, result)
})
.catch(function (err) {
done(err);
})
return;
}
return promise
}

@@ -368,0 +505,0 @@

{
"name": "mailchimp-api-v3",
"version": "1.1.0",
"version": "1.2.0",
"description": "Mailchimp wrapper for v3 of the mailchimp api, with transparant handling of batch operations",

@@ -29,2 +29,3 @@ "main": "index.js",

"dependencies": {
"bluebird": "^3.4.0",
"lodash": "^3.10.1",

@@ -31,0 +32,0 @@ "request": "^2.67.0",

# node-mailchimp
Mailchimp api wrapper for v3 of the mailchimp api, with batch handling
Mailchimp api wrapper for v3 of the mailchimp api, with batch handling. Supports both promise and callback handling.

@@ -10,2 +10,3 @@ ```javascript

//Callback style
mailchimp.get({

@@ -16,2 +17,13 @@ path : '/lists/id1'

})
//Promise style
mailchimp.get({
path : '/lists/id1'
})
.then(function (result) {
...
})
.catch(function (err) {
...
})
```

@@ -22,2 +34,3 @@

```javascript
//Callback style
mailchimp.batch([

@@ -34,2 +47,19 @@ {

})
//Promise style
mailchimp.batch([
{
method : 'get',
path : '/lists/id1'
},
{
method : 'get',
path : '/lists/id2'
}])
.then(function (results) {
//results[0] same as result in previous example
})
.catch(function (err) {
...
})
```

@@ -50,2 +80,6 @@

### Promise support
In all calls you can omit the callback, and a promise will be returned instead.
### Initialization

@@ -71,3 +105,3 @@

},
params : {
query : {
//query string parameters, see mailchimp documentation for each call

@@ -80,15 +114,32 @@ }

For each request method, convenience calls exists to default to that method:
For each request method, convenience calls exists to make common calls:
```javascript
mailchimp.get({}, cb)
mailchimp.post({}, cb)
mailchimp.put({}, cb)
mailchimp.patch({}, cb)
mailchimp.delete({}, cb)
mailchimp.get(path, [query], [callback])
mailchimp.post(path, [body], [callback])
mailchimp.put(path, [body], [callback])
mailchimp.patch(path, [body], [callback])
mailchimp.delete(path, [callback])
```
This allows shorthand forms like:
```javascript
mailchimp.get('/lists')
.then(function(results) {
...
})
mailchimp.post('/lists/id', {
email : '...'
...
})
.then(function(results) {
...
})
```
### Batch Calls
```javascript
var calls = [

@@ -124,2 +175,32 @@ {

* `interval` if `wait` is true, the interval to poll for the status of the batch call, defaults to 2000ms
* `unpack` if `wait` is true, whether or not to get and unpack the results of the batch operation, and return the response bodies.
* `unpack` if `wait` is true, whether or not to get and unpack the results of the batch operation, and return the response bodies.
* `verbose` if `wait` is true, whether or not to log progress to the console
#### BatchWait
```javascript
mailchimp.batchWait(batch_id, callback, {
interval : 2000,
unpack : true,
})
```
If you call `batch` with `wait : false`, you can use the returned batch id to resume pooling and unpacking the results at a later time.
This also allows you to "reconnect" to a batch operation after a crash or similar.
#### Single operation batch
If you pass a single operation, instaed of an array to `batch`, the result will be the same as if you ran the operation without batch.
This is very useful if you want to make calls without paging, where a normal call would take to long, and likely time out.
```javascript
mailchimp.batch({
method : 'get',
path : '/lists/id/members',
query : {
count : 10000000000,
}
}, function (err, result) {
//result is the same as a normal .get request
})
```

@@ -45,2 +45,295 @@ var api_key = process.env.MAILCHIMP_TEST_API_KEY

})
it('should handle simple get with promise', function (done) {
mailchimp.get({
path : '/lists',
}).then(function (result) {
assert.ok(result)
assert.ok(result.lists)
done()
}).catch(function (err) {
done(new Error(err));
})
})
it('should handle wrong path', function (done) {
mailchimp.get({
path : '/wrong',
}, function (err, result) {
assert.equal(err.status, 404);
done()
})
})
it('should handle wrong path with promise', function (done) {
mailchimp.get({
path : '/wrong',
}).then(function (result) {
//Error
done(result)
}).catch(function (err) {
assert.equal(err.status, 404);
done()
})
})
it('should handle get with just a path', function (done) {
mailchimp.get('/lists', function (err, result) {
assert.equal(err, null);
assert.ok(result)
assert.ok(result.lists)
done()
})
})
it('should handle get with just a path with promise', function (done) {
mailchimp.get('/lists')
.then(function (result) {
assert.ok(result);
assert.ok(result.lists);
done();
})
.catch(function (err) {
done(new Error(err))
})
})
it('should handle get with a path and query', function (done) {
mailchimp.get('/lists', {offset : 1}, function (err, result) {
assert.equal(err, null);
assert.ok(result)
assert.ok(result.lists)
done()
})
})
it('should handle get with a path and query with promise', function (done) {
mailchimp.get('/lists', {offset : 1})
.then(function (result) {
assert.ok(result)
assert.ok(result.lists)
done()
})
.catch(function (err) {
done(new Error(err))
})
})
})
describe('batch mailchimp api methods', function () {
var mailchimp = new Mailchimp(api_key);
it('should handle batch with single non-array command', function (done) {
this.timeout(100000)
mailchimp.batch({
method : 'get',
path : '/lists',
}, {
verbose : false
}).then(function (result) {
assert.ok(result)
assert.ok(result.lists)
done()
}).catch(function (err) {
done(new Error(err));
})
})
it('should handle batch operations with no wait', function (done) {
this.timeout(100000)
mailchimp.batch([
{
method : 'get',
path : '/lists',
},
{
method : 'get',
path : '/lists',
},
], function (err, result) {
assert.equal(err, null);
assert.ok(result.submitted_at);
assert.ok(result.status);
assert.ok(result.id);
done()
}, {
verbose : false,
wait : false
})
})
it('should handle batch operations with no wait with promises', function (done) {
this.timeout(100000)
mailchimp.batch([
{
method : 'get',
path : '/lists',
},
{
method : 'get',
path : '/lists',
},
], {
verbose : false,
wait : false
}).then(function (result) {
assert.ok(result.submitted_at);
assert.ok(result.status);
assert.ok(result.id);
done()
}).catch(function (err) {
done(new Error(err));
})
})
it('should handle batch operations with no unpack', function (done) {
this.timeout(100000)
mailchimp.batch([
{
method : 'get',
path : '/lists',
},
{
method : 'get',
path : '/lists',
},
], function (err, result) {
assert.equal(err, null);
assert.ok(result.submitted_at);
assert.equal(result.status, 'finished');
assert.equal(result.total_operations, 2);
done()
}, {
verbose : false,
wait : true,
unpack : false,
})
})
it('should handle batch operations with no unpack with promise', function (done) {
this.timeout(100000)
mailchimp.batch([
{
method : 'get',
path : '/lists',
},
{
method : 'get',
path : '/lists',
},
], {
verbose : false,
wait : true,
unpack : false,
}).then(function (result) {
assert.ok(result.submitted_at);
assert.equal(result.status, 'finished');
assert.equal(result.total_operations, 2);
done()
}).catch(function (err) {
done(new Error(err));
})
})
it('should handle batch operations', function (done) {
this.timeout(100000)
mailchimp.batch([
{
method : 'get',
path : '/lists',
},
{
method : 'get',
path : '/lists',
},
], function (err, result) {
assert.equal(err, null);
assert.equal(result.length, 2)
done()
}, {
verbose : false
})
})
it('should handle batch operations with promise', function (done) {
this.timeout(100000)
mailchimp.batch([
{
method : 'get',
path : '/lists',
},
{
method : 'get',
path : '/lists',
},
], {
verbose : false
}).then(function (result) {
assert.equal(result.length, 2)
done()
}).catch(function (err) {
done(new Error(err));
})
})
it('should handle batchWait operations', function (done) {
this.timeout(100000)
var batch_id;
mailchimp.batch([
{
method : 'get',
path : '/lists',
},
{
method : 'get',
path : '/lists',
},
], {
verbose : false,
wait : false,
}).then(function (result) {
batch_id = result.id;
mailchimp.batchWait(batch_id, function (err, result) {
assert.equal(err, null);
assert.equal(result.length, 2)
done();
}, {verbose : false});
})
})
it('should handle batchWait operations with promise', function (done) {
this.timeout(100000)
var batch_id;
mailchimp.batch([
{
method : 'get',
path : '/lists',
},
{
method : 'get',
path : '/lists',
},
], {
verbose : false,
wait : false,
}).then(function (result) {
batch_id = result.id;
return mailchimp.batchWait(batch_id, {verbose : false});
}).then(function (result) {
assert.equal(result.length, 2)
done();
}).catch(function (err) {
done(new Error(err));
})
})
})
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