Skip to content

Commit 2a8853c

Browse files
committed
1.0.0
1 parent 541f6f0 commit 2a8853c

File tree

11 files changed

+212
-227
lines changed

11 files changed

+212
-227
lines changed

HISTORY.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
1.0.0 / 2016-10-27
2+
==================
3+
* When no callback is provided, all API functions now return a native JS `Promise`
4+
* Removed the non get/set method calls like `database.release(...)` deprecated in release `0.8.0`
5+
16
0.9.1 / 2016-10-24
27
==================
38
* Upgraded OAuth library to `oauth-1.0a` v2.0.0

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
* Covers all API endpoints
1010
* Supports [pagination](http://www.discogs.com/developers/#page:home,header:home-pagination), [rate limiting](http://www.discogs.com/developers/#page:home,header:home-rate-limiting), etc.
11-
* All database, marketplace and user functions implement a standard `function(err, data, rateLimit)` format for the callback
11+
* All database, marketplace and user functions implement a standard `function(err, data, rateLimit)` format for the callback or return a
12+
native JS [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) when no callback is provided
1213
* Easy access to protected endpoints with `Discogs Auth`
1314
* Includes OAuth 1.0a tools. Just plug in your consumer key and secret and do the OAuth dance
1415
* API functions grouped in their own namespace for easy access and isolation
@@ -67,6 +68,20 @@ col.getReleases('USER_NAME', 0, {page: 2, per_page: 75}, function(err, data){
6768
});
6869
```
6970

71+
### Promises
72+
When no callback is provided, the API functions return a native JS [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) for easy chaining.
73+
74+
```javascript
75+
var db = new Discogs().database();
76+
db.getRelease(1)
77+
.then(function(release){
78+
return db.getArtist(release.artists[0].id);
79+
})
80+
.then(function(artist){
81+
console.log(artist.name);
82+
});
83+
```
84+
7085
### Output format
7186
User, artist and label profiles can be formatted in different ways: `plaintext`, `html` and `discogs`. `disconnect` defaults to `discogs`, but the output format can be set for each client instance.
7287
```javascript
@@ -111,6 +126,7 @@ app.get('/authorize', function(req, res){
111126
);
112127
});
113128
```
129+
114130
#### 2. Authorize
115131
After redirection to the Discogs authorize URL in step 1, authorize the application.
116132

lib/client.js

Lines changed: 74 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ var https = require('https'),
55
url = require('url'),
66
pkg = require('../package.json'),
77
error = require('./error.js'),
8-
util = require('./util.js'),
9-
deprecate = require('depd')('disconnect');
8+
util = require('./util.js');
109

1110
module.exports = DiscogsClient;
1211

@@ -38,7 +37,7 @@ var queue = require('./queue.js')({
3837
* Object constructor
3938
* @param {string} [userAgent] - The name of the user agent to use to make API calls
4039
* @param {object} [auth] - Optional authorization data object
41-
* @returns {DiscogsClient}
40+
* @return {DiscogsClient}
4241
*/
4342

4443
function DiscogsClient(userAgent, auth){
@@ -73,7 +72,7 @@ function DiscogsClient(userAgent, auth){
7372
/**
7473
* Override the default configuration
7574
* @param {object} customConfig - Custom configuration object for Browserify/CORS/Proxy use cases
76-
* @returns {DiscogsClient}
75+
* @return {DiscogsClient}
7776
*/
7877
DiscogsClient.prototype.setConfig = function(customConfig){
7978
util.merge(this.config, customConfig);
@@ -87,7 +86,7 @@ DiscogsClient.prototype.setConfig = function(customConfig){
8786
/**
8887
* Return whether the client is authenticated for the optionally given access level
8988
* @param {number} [level] - Optional authentication level
90-
* @returns {boolean}
89+
* @return {boolean}
9190
*/
9291

9392
DiscogsClient.prototype.authenticated = function(level){
@@ -98,33 +97,35 @@ DiscogsClient.prototype.authenticated = function(level){
9897
/**
9998
* Test authentication by getting the identity resource for the authenticated user
10099
* @param {function} callback - Callback function receiving the data
100+
* @return {DiscogsClient|Promise}
101101
*/
102102

103103
DiscogsClient.prototype.getIdentity = function(callback){
104-
this.get({url: '/oauth/identity', authLevel: 2}, callback);
104+
return this.get({url: '/oauth/identity', authLevel: 2}, callback);
105105
};
106106

107-
DiscogsClient.prototype.identity = deprecate.function(DiscogsClient.prototype.getIdentity,
108-
'client.identity: Use client.getIdentity instead');
109-
110107
/**
111108
* Get info about the Discogs API and this client
112109
* @param {function} callback - Callback function receiving the data
113110
*/
114111

115112
DiscogsClient.prototype.about = function(callback){
116-
var self = this;
117-
this.get('', function(err, data){
118-
if(data){
119-
data.disconnect = {
120-
version: pkg.version,
121-
userAgent: self.config.userAgent,
122-
authMethod: (self.auth ? self.auth.method : 'none'),
123-
authLevel: (self.auth ? self.auth.level : 0)
124-
};
125-
}
126-
callback(err, data);
127-
});
113+
var clientInfo = {
114+
version: pkg.version,
115+
userAgent: this.config.userAgent,
116+
authMethod: (this.auth ? this.auth.method : 'none'),
117+
authLevel: (this.auth ? this.auth.level : 0)
118+
};
119+
if(typeof callback === 'function'){
120+
return this.get('', function(err, data){
121+
data && (data.disconnect = clientInfo);
122+
callback(err, data);
123+
});
124+
}
125+
return this.get('').then(function(data){
126+
data && (data.disconnect = clientInfo);
127+
return data;
128+
});
128129
};
129130

130131
/**
@@ -135,8 +136,8 @@ DiscogsClient.prototype.about = function(callback){
135136
* method: '', // Defaults to GET
136137
* data: {} // POST/PUT data as an object
137138
* }
138-
* @param {function} [callback] - Callback function receiving the data
139-
* @returns {DiscogsClient}
139+
* @param {function} callback - Callback function receiving the data
140+
* @return {DiscogsClient}
140141
*/
141142

142143
DiscogsClient.prototype._rawRequest = function(options, callback){
@@ -180,7 +181,7 @@ DiscogsClient.prototype._rawRequest = function(options, callback){
180181
}
181182

182183
// Set the HTTPS request options
183-
var options = {
184+
var requestOptions = {
184185
host: urlParts.host||this.config.host,
185186
port: urlParts.port||this.config.port,
186187
path: urlParts.path,
@@ -189,19 +190,17 @@ DiscogsClient.prototype._rawRequest = function(options, callback){
189190
};
190191

191192
// Build the HTTPS request
192-
var req = https.request(options, function(res){
193+
var req = https.request(requestOptions, function(res){
193194
var data = '', rateLimit = null, add = function(chunk){ data += chunk.toString(); };
194195

195196
// Pass the data to the callback and pass an error on unsuccessful HTTP status
196197
var passData = function(){
197-
if(typeof callback === 'function'){
198-
var err = null, status = parseInt(res.statusCode, 10);
199-
if(status > 399){ // Unsuccessful HTTP status? Then pass an error to the callback
200-
var match = data.match(/^\{"message": "(.+)"\}/i);
201-
err = new error.DiscogsError(status, ((match&&match[1]) ? match[1] : null));
202-
}
203-
callback(err, data, rateLimit);
198+
var err = null, status = parseInt(res.statusCode, 10);
199+
if(status > 399){ // Unsuccessful HTTP status? Then pass an error to the callback
200+
var match = data.match(/^\{"message": "(.+)"\}/i);
201+
err = new error.DiscogsError(status, ((match&&match[1]) ? match[1] : null));
204202
}
203+
callback(err, data, rateLimit);
205204
};
206205

207206
// Find and add rate limiting when present
@@ -230,7 +229,7 @@ DiscogsClient.prototype._rawRequest = function(options, callback){
230229
res.on('data', add).on('end', passData);
231230
}
232231
}).on('error', function(err){
233-
if(typeof callback === 'function'){ callback(err); }
232+
callback(err);
234233
});
235234

236235
// When present, write the data to the request
@@ -249,19 +248,38 @@ DiscogsClient.prototype._rawRequest = function(options, callback){
249248
* data: {} // POST/PUT data as an object
250249
* }
251250
* @param {function} [callback] - Callback function receiving the data
252-
* @returns {DiscogsClient}
251+
* @return {DiscogsClient|Promise}
253252
*/
254253

255254
DiscogsClient.prototype._request = function(options, callback){
256-
var self = this, hasCb = (typeof callback === 'function'),
255+
var client = this,
257256
doRequest = function(){
258-
self._rawRequest(options, function(err, data, rateLimit){
257+
client._rawRequest(options, function(err, data, rateLimit){
259258
if(data && options.json && (data.indexOf('<!') !== 0)){
260259
data = JSON.parse(data);
261260
}
262-
if(hasCb){ callback(err, data, rateLimit); }
261+
callback(err, data, rateLimit);
263262
});
263+
},
264+
prepareRequest = function(){
265+
// Check whether authentication is required
266+
if(!options.authLevel || client.authenticated(options.authLevel)){
267+
if(options.queue){ // Add API request to the execution queue
268+
queue.add(function(err){
269+
if(!err){
270+
doRequest(callback);
271+
}else{ // Can't add to the queue because it's full
272+
callback(err);
273+
}
274+
});
275+
}else{ // Don't queue, just do the request
276+
doRequest(callback);
277+
}
278+
}else{
279+
callback(new error.AuthError());
280+
}
264281
};
282+
265283
// By default, queue requests
266284
if(!options.hasOwnProperty('queue')){
267285
options.queue = true;
@@ -270,30 +288,25 @@ DiscogsClient.prototype._request = function(options, callback){
270288
if(!options.hasOwnProperty('json')){
271289
options.json = true;
272290
}
273-
// Check whether authentication is required
274-
if(!options.authLevel || this.authenticated(options.authLevel)){
275-
if(options.queue){ // Add API request to the execution queue
276-
queue.add(function(err){
277-
if(!err){
278-
doRequest();
279-
}else{ // Can't add to the queue because it's full
280-
if(hasCb){ callback(err); }
281-
}
282-
});
283-
}else{ // Don't queue, just do the request
284-
doRequest();
285-
}
286-
}else{
287-
if(hasCb){ callback(new error.AuthError()); }
291+
292+
if(typeof callback === 'function'){
293+
prepareRequest();
294+
return this;
288295
}
289-
return this;
296+
// No callback provided? Return a Promise
297+
return new Promise(function(resolve, reject){
298+
callback = function(err, data){
299+
(err && reject(err)) || resolve(data);
300+
};
301+
prepareRequest();
302+
});
290303
};
291304

292305
/**
293306
* Perform a GET request against the Discogs API
294307
* @param {(object|string)} options - Request options object or an url
295308
* @param {function} [callback] - Callback function receiving the data
296-
* @returns {DiscogsClient}
309+
* @return {DiscogsClient|Promise}
297310
*/
298311

299312
DiscogsClient.prototype.get = function(options, callback){
@@ -306,7 +319,7 @@ DiscogsClient.prototype.get = function(options, callback){
306319
* @param {(object|string)} options - Request options object or an url
307320
* @param {object} data - POST data
308321
* @param {function} [callback] - Callback function receiving the data
309-
* @returns {DiscogsClient}
322+
* @return {DiscogsClient|Promise}
310323
*/
311324

312325
DiscogsClient.prototype.post = function(options, data, callback){
@@ -319,7 +332,7 @@ DiscogsClient.prototype.post = function(options, data, callback){
319332
* @param {(object|string)} options - Request options object or an url
320333
* @param {object} data - PUT data
321334
* @param {function} [callback] - Callback function receiving the data
322-
* @returns {DiscogsClient}
335+
* @return {DiscogsClient|Promise}
323336
*/
324337

325338
DiscogsClient.prototype.put = function(options, data, callback){
@@ -331,7 +344,7 @@ DiscogsClient.prototype.put = function(options, data, callback){
331344
* Perform a DELETE request against the Discogs API
332345
* @param {(object|string)} options - Request options object or an url
333346
* @param {function} [callback] - Callback function receiving the data
334-
* @returns {DiscogsClient}
347+
* @return {DiscogsClient|Promise}
335348
*/
336349

337350
DiscogsClient.prototype.delete = function(options, callback){
@@ -341,7 +354,7 @@ DiscogsClient.prototype.delete = function(options, callback){
341354

342355
/**
343356
* Get an instance of the Discogs OAuth class
344-
* @returns {DiscogsOAuth}
357+
* @return {DiscogsOAuth}
345358
*/
346359

347360
DiscogsClient.prototype.oauth = function(){
@@ -351,7 +364,7 @@ DiscogsClient.prototype.oauth = function(){
351364

352365
/**
353366
* Expose the database functions and pass the current instance
354-
* @returns {object}
367+
* @return {object}
355368
*/
356369

357370
DiscogsClient.prototype.database = function(){
@@ -360,7 +373,7 @@ DiscogsClient.prototype.database = function(){
360373

361374
/**
362375
* Expose the marketplace functions and pass the current instance
363-
* @returns {object}
376+
* @return {object}
364377
*/
365378

366379
DiscogsClient.prototype.marketplace = function(){
@@ -369,7 +382,7 @@ DiscogsClient.prototype.marketplace = function(){
369382

370383
/**
371384
* Expose the user functions and pass the current instance
372-
* @returns {object}
385+
* @return {object}
373386
*/
374387

375388
DiscogsClient.prototype.user = function(){

0 commit comments

Comments
 (0)