1
+ var assert = require ( 'assert' ) ;
2
+ var OAuth = require ( 'OAuth' ) ;
3
+ var url = require ( 'url' ) ;
4
+ var Promise = require ( 'promise' ) ;
5
+
6
+ require ( 'extend-error' ) ;
7
+ var HttpApiError = Error . extend ( 'HttpApiError' ) ;
8
+
9
+ var Client = function ( options ) {
10
+ assert ( options . key , 'Must provide API key' ) ;
11
+ assert ( options . secret , 'Must provide API secret' ) ;
12
+ assert ( options . callbackURL , 'Must provide API callbackURL' ) ;
13
+ assert ( options . requestUrl , 'Must provide requestUrl' ) ;
14
+ assert ( options . accessUrl , 'Must provide accessUrl' ) ;
15
+ assert ( options . apiHostName , 'Must provide apiHostName' ) ;
16
+
17
+ this . apiKey = options . key ;
18
+ this . apiSecret = options . secret ;
19
+ this . callbackURL = options . callbackURL ;
20
+ this . apiHostName = options . apiHostName ;
21
+
22
+ this . oauthClient = new OAuth . OAuth (
23
+ options . requestUrl ,
24
+ options . accessUrl ,
25
+ this . apiKey ,
26
+ this . apiSecret ,
27
+ '1.0' ,
28
+ this . callbackURL ,
29
+ 'HMAC-SHA1' ) ;
30
+ } ;
31
+
32
+ Client . prototype . auth = function ( token , secret ) {
33
+ assert ( token , 'Must provide token' ) ;
34
+ assert ( secret , 'Must provide secret' ) ;
35
+
36
+ this . authenticatedToken = token ;
37
+ this . authenticatedSecret = secret ;
38
+ return this ;
39
+ } ;
40
+
41
+ Client . prototype . get = function ( path , pageOrQuery ) {
42
+ assert ( this . authenticatedToken , 'Must set authentication token first' ) ;
43
+ assert ( this . authenticatedSecret , 'Must set authentication secret first' ) ;
44
+
45
+ var url = buildUrl ( this . apiKey , this . apiSecret , this . apiHostName , path , pageOrQuery ) ;
46
+ return new Promise ( function ( resolve , reject ) {
47
+ var responseHandler = createResponseHandler ( resolve , reject ) ;
48
+ this . oauthClient . get ( url , this . authenticatedToken , this . authenticatedSecret , responseHandler ) ;
49
+ } . bind ( this ) ) ;
50
+ } ;
51
+
52
+ Client . prototype . put = function ( path , content ) {
53
+ assert ( this . authenticatedToken , 'Must set authentication token first' ) ;
54
+ assert ( this . authenticatedSecret , 'Must set authentication secret first' ) ;
55
+
56
+ var url = buildUrl ( this . apiKey , this . apiSecret , this . apiHostName , path ) ;
57
+ return new Promise ( function ( resolve , reject ) {
58
+ var responseHandler = createResponseHandler ( resolve , reject ) ;
59
+ this . oauthClient . put ( url , this . authenticatedToken , this . authenticatedSecret , content , responseHandler ) ;
60
+ } . bind ( this ) ) ;
61
+ } ;
62
+
63
+ Client . prototype . post = function ( path , content ) {
64
+ assert ( this . authenticatedToken , 'Must set authentication token first' ) ;
65
+ assert ( this . authenticatedSecret , 'Must set authentication secret first' ) ;
66
+
67
+ var url = buildUrl ( this . apiKey , this . apiSecret , this . apiHostName , path ) ;
68
+ return new Promise ( function ( resolve , reject ) {
69
+ var responseHandler = createResponseHandler ( resolve , reject ) ;
70
+ this . oauthClient . post ( url , this . authenticatedToken , this . authenticatedSecret , content , responseHandler ) ;
71
+ } . bind ( this ) ) ;
72
+ } ;
73
+
74
+ Client . prototype [ 'delete' ] = function ( path ) {
75
+ assert ( this . authenticatedToken , 'Must set authentication token first' ) ;
76
+ assert ( this . authenticatedSecret , 'Must set authentication secret first' ) ;
77
+
78
+ var url = buildUrl ( this . apiKey , this . apiSecret , this . apiHostName , path ) ;
79
+ return new Promise ( function ( resolve , reject ) {
80
+ var responseHandler = createResponseHandler ( resolve , reject ) ;
81
+ this . oauthClient [ 'delete' ] ( url , this . authenticatedToken , this . authenticatedSecret , responseHandler ) ;
82
+ } . bind ( this ) ) ;
83
+ } ;
84
+
85
+ Client . prototype . requestToken = function ( extraParams ) {
86
+ return new Promise ( function ( resolve , reject ) {
87
+ this . oauthClient . getOAuthRequestToken ( extraParams || { } , function ( err , oauthToken , oauthTokenSecret , parsedQueryString ) {
88
+ if ( err ) {
89
+ return reject ( err ) ;
90
+ }
91
+ resolve ( {
92
+ token : oauthToken ,
93
+ tokenSecret : oauthTokenSecret ,
94
+ authorizeUrl : parsedQueryString . login_url
95
+ } ) ;
96
+ } ) ;
97
+ } . bind ( this ) ) ;
98
+ } ;
99
+
100
+ Client . prototype . accessToken = function ( token , secret , verifier ) {
101
+ return new Promise ( function ( resolve , reject ) {
102
+ this . oauthClient . getOAuthAccessToken ( token , secret , verifier , function ( err , oauthAccessToken , oauthAccessTokenSecret ) {
103
+ if ( err ) {
104
+ return reject ( err ) ;
105
+ }
106
+ resolve ( {
107
+ token : oauthAccessToken ,
108
+ tokenSecret : oauthAccessTokenSecret
109
+ } ) ;
110
+ } ) ;
111
+ } . bind ( this ) ) ;
112
+ } ;
113
+
114
+ function createResponseHandler ( resolve , reject ) {
115
+ return function responseHandler ( err , data , res ) {
116
+ if ( res . statusCode . toString ( ) [ 0 ] !== '2' ) {
117
+ return reject ( new HttpApiError ( { statusCode : res . statusCode , body : data } ) ) ;
118
+ }
119
+ if ( typeof data === 'string' ) {
120
+ try {
121
+ var parsedBody = JSON . parse ( data || '{}' ) ;
122
+ resolve ( {
123
+ statusCode : res . statusCode ,
124
+ body : parsedBody ,
125
+ headers : res . headers
126
+ } ) ;
127
+ } catch ( err ) {
128
+ reject ( 'Error parsing JSON response from API. Error:' + err ) ;
129
+ }
130
+ }
131
+ } ;
132
+ }
133
+
134
+ function buildUrl ( apiKey , apiSecret , apiHostName , path , pageOrQuery ) {
135
+ if ( apiKey === null ) {
136
+ throw new Error ( 'Must provide apiKey' ) ;
137
+ }
138
+ if ( apiSecret === null ) {
139
+ throw new Error ( 'Must provide apiSecret' ) ;
140
+ }
141
+ if ( path === null ) {
142
+ throw new Error ( 'Must provide a path' ) ;
143
+ }
144
+ var query = ( pageOrQuery && typeof pageOrQuery === 'object' )
145
+ ? pageOrQuery
146
+ : { } ;
147
+ if ( apiKey && ! apiSecret ) {
148
+ query . api_key = this . apiKey ;
149
+ }
150
+ return url . format ( {
151
+ protocol : "https:" ,
152
+ hostname : apiHostName ,
153
+ pathname : path ,
154
+ query : query
155
+ } ) ;
156
+ }
157
+
158
+ module . exports = Client ;
0 commit comments