Skip to content

Commit 9feafae

Browse files
author
Will Myers
authored
Add accounts resource (#5)
* Add accounts resource * Add options to #transactions * Implement PR Feedback
1 parent 961e62f commit 9feafae

15 files changed

Lines changed: 404 additions & 45 deletions

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2.0.0 August 24, 2016
2+
- Added `accounts` resource
3+
+ `accounts#all`
4+
+ `accounts#transactions`
5+
- Changed response structure. All responses are now an object with two attributes: `data` containing what was previously the entire response and `meta` containing additional properties about a request.
6+
17
1.0.0 August 5, 2016
28
- Initial Release
39

README.md

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,32 @@ promiseCreator(resolver) {
9595
}
9696
```
9797

98-
The returned promise will either reject with an `Error` or resolve with the API response.
98+
The returned promise will either reject with an `Error` or resolve with the API response object.
99+
100+
## Responses
101+
102+
All responses will assume the following shape:
103+
104+
```javascript
105+
{
106+
data,
107+
meta: {
108+
next,
109+
previous
110+
}
111+
}
112+
```
113+
114+
The `data` key will contain any resource data received from the API and the `meta` key will contain high-order information pertaining to the request.
115+
116+
##### meta
117+
118+
* `next`: For any paged resource, `next` will be a cursor to supply for the next page of results.
119+
* `previous`: For any paged resource, `previous` will be a cursor to supply for the previous page of results.
99120

100121
## Resources
101122

102-
We currently expose only one resource to manage, `Orders`.
123+
We currently expose two resource to manage, `Orders` and `Accounts`.
103124

104125
### Orders
105126

@@ -128,6 +149,7 @@ client.orders.get('btnorder-XXX', function(err, res) {
128149
// ...
129150
});
130151
```
152+
131153
##### Update
132154

133155
```javascript
@@ -148,6 +170,50 @@ client.orders.del('btnorder-XXX', function(err, res) {
148170
});
149171
```
150172

173+
### Accounts
174+
175+
##### All
176+
177+
```javascript
178+
var client = require('./index')('sk-XXX');
179+
180+
client.accounts.all(function(err, res) {
181+
// ...
182+
});
183+
```
184+
185+
##### Transactions
186+
187+
Transactions are a paged resource. The response object will contain properties `meta.next` and `meta.previous` which can be supplied to subsequent invocations of `#transactions` to fetch additional results.
188+
189+
`#transactions` accepts an optional second parameter, `options` which may define the follow keys to narrow results:
190+
191+
###### options
192+
193+
* `cursor`: An API cursor to fetch a specific set of results
194+
* `start`: An ISO-8601 datetime string to filter only transactions after `start`
195+
* `end`: An ISO-8601 datetime string to filter only transactions before `end`
196+
197+
```javascript
198+
var client = require('./index')('sk-XXX');
199+
200+
// without options argument
201+
//
202+
client.accounts.transactions('acc-1', function(err, res) {
203+
// ...
204+
});
205+
206+
// with options argument
207+
//
208+
client.accounts.transactions('acc-1', {
209+
cursor: 'cXw',
210+
start: '2015-01-01T00:00:00Z',
211+
end: '2016-01-01T00:00:00Z'
212+
}, function(err, res) {
213+
// ...
214+
});
215+
```
216+
151217
## Contributing
152218

153219
* Installing development dependencies: `npm install`

index.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var resources = require('./lib').resources;
22
var maybePromise = require('./lib').maybePromise;
3+
var request = require('./lib').request;
34
var version = require('./package.json').version;
45

56
module.exports = function client(apiKey, config) {
@@ -31,7 +32,13 @@ module.exports = function client(apiKey, config) {
3132
}
3233
};
3334

35+
var maybePromiseRequest = maybePromise(
36+
request(config.timeout),
37+
config.promise
38+
);
39+
3440
return {
35-
orders: resources.orders(requestOptions, config)
41+
orders: resources.orders(requestOptions, maybePromiseRequest),
42+
accounts: resources.accounts(requestOptions, maybePromiseRequest)
3643
};
3744
}

lib/compact.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
3+
function compact(obj) {
4+
//
5+
// compact removes false-y values from an object
6+
//
7+
// ## Usage
8+
//
9+
// compact({ a: 1, b: 0, c: null, d: undefined, e: '', f: NaN })
10+
// // => { a: 1 }
11+
//
12+
// @param {Object} obj the object to compacy
13+
// @returns {Object} a new object with only truth-y values remaning
14+
//
15+
var res = {};
16+
17+
for (var key in obj) {
18+
if (obj[key]) {
19+
res[key] = obj[key];
20+
}
21+
}
22+
23+
return res;
24+
}
25+
26+
module.exports = compact;

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
module.exports = {
44
resources: require('./resources'),
5+
compact: require('./compact'),
56
maybePromise: require('./maybePromise'),
67
merge: require('./merge'),
78
once: require('./once'),

lib/request.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
var https = require('https');
4+
var parse = require('url').parse;
45
var once = require('./once');
56

67
function request(timeout) {
@@ -86,7 +87,7 @@ function responseHandler(callback) {
8687
var status = response.meta.status;
8788

8889
if (status === 'ok') {
89-
return callback(null, response.object);
90+
return callback(null, formatResponse(response));
9091
} else if (status === 'error') {
9192
if (typeof response.error !== 'object' || !response.error.message) {
9293
return callback(new Error('Invalid response: ' + rawResponse), null);
@@ -113,4 +114,23 @@ function timeoutHandler(callback, req) {
113114
};
114115
}
115116

117+
function formatResponse(response) {
118+
return {
119+
data: response.object !== undefined ? response.object : response.objects,
120+
meta: {
121+
next: formatCursor(response.meta.next),
122+
previous: formatCursor(response.meta.previous)
123+
}
124+
};
125+
}
126+
127+
function formatCursor(url) {
128+
if (typeof url === 'string') {
129+
var parsed = parse(url, true);
130+
return parsed.query.cursor || null;
131+
} else {
132+
return null;
133+
}
134+
}
135+
116136
module.exports = request;

lib/resources/accounts.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
'use strict';
2+
3+
var querystring = require('querystring');
4+
var merge = require('../merge');
5+
var compact = require('../compact');
6+
7+
function accounts(requestOptions, maybePromiseRequest) {
8+
return {
9+
all: function all(callback) {
10+
//
11+
// Gets an index of all available accounts.
12+
//
13+
// @callback invoked iff config.promise isn't valid
14+
// @returns {Object=} a promise or undefined, depending on
15+
// `config.promise`
16+
//
17+
var options = merge(requestOptions, {
18+
method: 'GET',
19+
path: '/v1/affiliation/accounts'
20+
});
21+
22+
return maybePromiseRequest(options, callback);
23+
},
24+
transactions: function transactions(accountId, params, callback) {
25+
//
26+
// Gets an index of all transactions for a given account.
27+
//
28+
// @param {string} accountId the account id
29+
// @param {Object=} params an object of optional options for the
30+
// request
31+
// @param {string=} params.cursor an opague string returned by a response
32+
// which returns consistent results
33+
// @param {string=} params.start an ISO-8601 datetime to filter results
34+
// @param {string=} params.end an ISO-8601 datetime to filter results
35+
// @callback invoked iff config.promise isn't valid
36+
// @returns {Object=} a promise or undefined, depending on
37+
// `config.promise`
38+
//
39+
if (typeof params === 'function') {
40+
callback = params;
41+
params = {};
42+
}
43+
44+
if (Object.prototype.toString.call(params) !== '[object Object]') {
45+
params = {};
46+
}
47+
48+
var queryString = querystring.stringify(compact({
49+
cursor: params.cursor,
50+
start: params.start,
51+
end: params.end
52+
}));
53+
54+
var query = queryString ? '?' + queryString : '';
55+
56+
var options = merge(requestOptions, {
57+
method: 'GET',
58+
path: '/v1/affiliation/accounts/' + accountId + '/transactions' + query
59+
});
60+
61+
return maybePromiseRequest(options, callback);
62+
}
63+
};
64+
}
65+
66+
module.exports = accounts;

lib/resources/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22

33
module.exports = {
4+
accounts: require('./accounts'),
45
orders: require('./orders')
56
};

lib/resources/orders.js

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
'use strict';
22

3-
var request = require('../request');
4-
var maybePromise = require('../maybePromise');
53
var merge = require('../merge');
64

7-
function orders(requestOptions, config) {
8-
var maybePromiseRequest = maybePromise(
9-
request(config.timeout),
10-
config.promise
11-
);
12-
5+
function orders(requestOptions, maybePromiseRequest) {
136
return {
147
get: function get(orderId, callback) {
158
//
16-
// Gets an order.
9+
// Gets an order.
1710
//
1811
// @param {string} orderId the order id
1912
// @callback invoked iff config.promise isn't valid
@@ -29,7 +22,7 @@ function orders(requestOptions, config) {
2922
},
3023
create: function create(order, callback) {
3124
//
32-
// Creates an order.
25+
// Creates an order.
3326
//
3427
// @param {Object} order the order
3528
// @callback invoked iff config.promise isn't valid
@@ -45,7 +38,7 @@ function orders(requestOptions, config) {
4538
},
4639
update: function update(orderId, order, callback) {
4740
//
48-
// Updates an order.
41+
// Updates an order.
4942
//
5043
// @param {string} orderId the order id
5144
// @param {Object} order the order
@@ -62,7 +55,7 @@ function orders(requestOptions, config) {
6255
},
6356
del: function del(orderId, callback) {
6457
//
65-
// Deletes an order.
58+
// Deletes an order.
6659
//
6760
// @param {string} orderId the order id
6861
// @callback invoked iff config.promise isn't valid

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "button-client-node",
3-
"version": "1.0.0",
3+
"version": "2.0.0",
44
"description": "node.js client for the Button Order API",
55
"main": "index.js",
66
"scripts": {

0 commit comments

Comments
 (0)