Coverage

77% line coverage
74% statement coverage
67% block coverage
124 SLOC

index.js

66% block coverage
13 SLOC
LineHitsStatementsSourceAction
1 not covered // twitter-rest-lite
2 not covered // =================
3 not covered //
4 not covered // A lightweight Twitter REST-API library with [OAuth](oauth.html)
5 not covered // and basic `POST`/`GET` [API](api.html) requests modules.
6 not covered //
7 not covered // For more convenient methods you should check [`twitter-rest`](https://github.com/ghostbar/twitter-rest).
8 not covered //
9 not covered
101100%var API = require('./lib/api');
111100%var OAuth = require('./lib/oauth');
12 not covered
13 not covered //
14 not covered // Quick Usage
15 not covered // -----------
16 not covered //
17 not covered // ```
18 not covered // var TwitterLib = require('twitter-rest-list'),
19 not covered // twitter = new TwitterLib({
20 not covered // consumer_key: "blahblahblah",
21 not covered // consumer_secret: "blahblahblah",
22 not covered // token: 'blah',
23 not covered // token_secret: 'blah',
24 not covered // callback: "randomurl"
25 not covered // });
26 not covered //
27 not covered // twitter.api.get('/statuses/user_timeline.json', {
28 not covered // screen_name: 'twitter',
29 not covered // count: 1
30 not covered // }, function (err, response) {
31 not covered // if (err) throw err;
32 not covered //
33 not covered // console.log(response);
34 not covered // });
35 not covered // ```
36 not covered /// #### PLEASE BE WARNED
37 not covered //
38 not covered // Using the complete `require` is only recommended if `token` and
39 not covered // `token_secret` already exists.
40 not covered //
41 not covered // Otherwise the API module will throw an Error since it does need those
42 not covered // two variables to do any of the calls./
43 not covered //
44 not covered // What's available on the initialized object?
45 not covered // -------------------------------------------
46 not covered //
47 not covered // Initializes two objects: `api` and `oauth`. You can initialize them
48 not covered // separated too (this is my preferred method).
49 not covered //
50 not covered // Parameters to initialize any of the exported Objects
51 not covered // ----------------------------------------------------
52 not covered //
53 not covered // All the exported functions expect an Object with the params:
54 not covered //
55 not covered // + `consumer_key` - (Required) consumer key given by Twitter
56 not covered // + `consumer_secret` - (Required) consumer secret given by Twitter
57 not covered // + `token` - (Optional) access_token key given by Twitter
58 not covered // + `token_secret` - (Required if `access_token_key` was given)
59 not covered // given by Twitter
60 not covered // + `callback` - (Optional) If your app is a desktop app write `oob`
61 not covered // (Out-Of-Band); if not then you should write your callback URL here
62 not covered // (which will rewrite the one configured on Twitter's developer dashboard.
63 not covered //
64 not covered
65 not covered //
66 not covered // Base URIs for Twitter API (These should be overwritten if to be used
67 not covered // with a compatible API)
68 not covered //
691100%var uri = { base: 'https://api.twitter.com/1.1', search: 'https://api.twitter.com/1.1/search' };
70 not covered
71 not covered //
72 not covered // Usage
73 not covered // -----
74 not covered //
75 not covered // ```
76 not covered // var TwitterLib = require('twitter-rest-lite'),
77 not covered // keys = {consumer_key: '...', consumer_secret: '...', token: '...', token_secret: '...' callback: '...'},
78 not covered // twitter = new TwitterLib(keys);
79 not covered //
80 not covered // /* twitter.oauth object */
81 not covered // twitter.oauth.requestToken( /* ... */ );
82 not covered // twitter.oauth.accessToken( /* ... */ );
83 not covered // twitter.oauth.authenticate( /* ... */ );
84 not covered // twitter.oauth.authorize( /* ... */ );
85 not covered //
86 not covered // /* twitter.api object */
87 not covered // twitter.api.get( /* ... */ );
88 not covered // twitter.api.post( /* ... */ );
89 not covered // ```
90 not covered //
91 not covered // #### PLEASE BE WARNED
92 not covered //
93 not covered // Using the complete `require` is only recommended if `token` and
94 not covered // `token_secret` already exists.
95 not covered //
96 not covered // Otherwise the API module will throw an Error since it does need those
97 not covered // two variables to do any of the calls.
98 not covered //
99 not covered // #### Code
1001100%module.exports = function(opts) {
101 not covered return {
102 not covered API: new API(uri, opts),
103 not covered OAuth: new OAuth(uri, opts)
104 not covered }
105 not covered };
106 not covered
107 not covered // OAuth Quick Usage
108 not covered // -----------------
109 not covered //
110 not covered // ```
111 not covered // var TwitterLib = require('twitter-rest-lite'),
112 not covered // toauth = new TwitterLib.OAuth({
113 not covered // consumer_key: 'blah',
114 not covered // consumer_secret: 'blah',
115 not covered // callback: 'randomurl'
116 not covered // });
117 not covered //
118 not covered // toauth.requestToken(function (err, response) {
119 not covered // if (err)
120 not covered // throw err;
121 not covered //
122 not covered // console.log(response);
123 not covered // });
124 not covered // ```
125 not covered //
126 not covered // More on the [OAuth module](oauth.html) documentation.
127 not covered //
128 not covered // #### Code
1291100%module.exports.OAuth = module.exports.oauth = function(opts) {
1305100% return new OAuth(uri, opts);
131 not covered };
132 not covered
133 not covered // API Quick Usage
134 not covered // ---------------
135 not covered //
136 not covered // ```
137 not covered // var TwitterLib = require('twitter-rest-lite'),
138 not covered // tapi = new TwitterLib.API({
139 not covered // consumer_key: 'blah',
140 not covered // consumer_secret: 'blah',
141 not covered // token: 'blah',
142 not covered // token_secret: 'blah',
143 not covered // callback: 'randomurl'
144 not covered // });
145 not covered //
146 not covered // tapi.get('/statuses/user_timeline.json', {
147 not covered // screen_name: 'twitter'
148 not covered // }, function (err, response) {
149 not covered // if (err)
150 not covered // throw err;
151 not covered //
152 not covered // console.log(response);
153 not covered // });
154 not covered // ```
155 not covered //
156 not covered // More on the [API module](api.html) documentation.
157 not covered //
158 not covered // #### Code
1591100%module.exports.API = module.exports.api = function(opts) {
1606100% return new API(uri, opts);
161 not covered };

lib/api.js

88% block coverage
44 SLOC
LineHitsStatementsSourceAction
11100%'use strict';
2 not covered
3 not covered //
4 not covered // Module: API
5 not covered // ===========
6 not covered //
7 not covered // Abstraction for the basic `GET`/`POST` operations of Twitter's REST API.
8 not covered //
9 not covered // Methods
10 not covered // -------
11 not covered //
12 not covered // + [Constructor/Initialize](#constructor)
13 not covered // + [GET](#get)
14 not covered // + [POST](#post)
15 not covered //
16 not covered // Usage
17 not covered // -----
18 not covered //
19 not covered // ```
20 not covered // var TwitterLib = require('twitter-rest-lite'),
21 not covered // api = new TwitterLib.API(var_with_keys);
22 not covered //
23 not covered // api.get(url, params, callback);
24 not covered //
25 not covered // api.post(url, data, callback);
26 not covered // ```
27 not covered //
28 not covered // <a name='constructor'></a>
29 not covered // Constructor
30 not covered // -----------
31 not covered //
32 not covered // #### Parameters
33 not covered //
34 not covered // + `uri` - base URI's to use (this should be provided by the
35 not covered // library itself)
36 not covered // + `opts` - `Object` with user-provided params
37 not covered // - `consumer_key` - required
38 not covered // - `consumer_secret` - required
39 not covered // - `token` - required
40 not covered // - `token_secret` - required
41 not covered //
42 not covered // #### Returns
43 not covered //
44 not covered // An `Object` with methods `get` and `post`.
45 not covered //
46 not covered // #### Code
47 not covered function API(uri, opts) {
486100% this.uri = uri;
49 not covered
50 not covered /* checking the required arguments */
516100% [ 'consumer_key', 'consumer_secret', 'token', 'token_secret' ].forEach(function (item) {
5222100% if (opts[item] == null)
531100% throw new Error('There\'s a required argument missing: ' + item);
54 not covered });
55 not covered
565100% this.opts = opts;
57 not covered }
58 not covered
59 not covered //
60 not covered // <a name='get'></a>
61 not covered // Public: Abstract GET request to the API
62 not covered // ---------------------------------------
63 not covered //
64 not covered // #### Parameters
65 not covered //
66 not covered // + `url` - String
67 not covered // + `params` - [Optional] Object with params to be passed
68 not covered // + `callback` - Callback Function
69 not covered //
70 not covered // #### Returns
71 not covered //
72 not covered // A `Callback` with two parameters. First is an `Error Object` and second
73 not covered // the body of the response in an `Object`.
74 not covered //
75 not covered // #### Example
76 not covered //
77 not covered // ```js
78 not covered // api.get('/statuses/user_timeline.json', {
79 not covered // screen_name: 'random',
80 not covered // count: 1
81 not covered // }, function (err, response) {
82 not covered // if (err)
83 not covered // throw err;
84 not covered //
85 not covered // console.log(response);
86 not covered // });
87 not covered // ```
88 not covered // #### Code
891100%API.prototype.get = function(url, params, callback) {
903100% var self = this;
913100% var request = require('request');
92 not covered
933100% if (url == null || url === '' || typeof(url) !== 'string') {
942100% if (callback != null) {
951100% return callback(new Error( 'Missing URL parameter' ));
96 not covered 'Missing URL parameter'
971100% throw new Error('Missing URL parameter');
98 not covered }
991100% url = self.uri.base + url;
100 not covered
1011100% if ((params != null) && (typeof params === 'object')) {
1021100% var qs = require('querystring');
1031100% url += '?' + qs.stringify(params);
104 not covered }
1051100% request({ method: 'GET', uri: url, oauth: self.opts, json: true, }, function (err, response, body) {
1061100% if (err)
1070 not covered return callback(err);
108 not covered
1091100% return callback(null, body);
110 not covered });
111 not covered };
112 not covered
113 not covered //
114 not covered // <a name='post'></a>
115 not covered // Public: abstract POST request to the API
116 not covered // ----------------------------------------
117 not covered //
118 not covered // #### Parameters
119 not covered //
120 not covered // + `url` - String
121 not covered // + `data` - [Required] Object with data
122 not covered // + `callback` - Callback Function
123 not covered //
124 not covered // #### Returns
125 not covered //
126 not covered // A `Callback` with two parameters: `Error Object` and `Object` with
127 not covered // body response from Twitter's API server.
128 not covered //
129 not covered // #### Example
130 not covered //
131 not covered // ```js
132 not covered // api.post('/statuses/update.json', {
133 not covered // status: "This is an update to twitter!"
134 not covered // }, function (err, response) {
135 not covered // if (err)
136 not covered // throw err;
137 not covered //
138 not covered // console.log(response);
139 not covered // });
140 not covered // ```
141 not covered //
142 not covered // #### Code
1431100%API.prototype.post = function(url, data, callback) {
1443100% var self = this;
1453100% var request = require('request');
1463100% var body = null;
147 not covered
1483100% if (url == null || url === '' || typeof(url) !== 'string') {
1492100% if (callback != null) {
1501100% return callback(new Error( 'Missing URL parameter' ));
151 not covered 'Missing URL parameter'
1521100% throw new Error('Missing URL parameter');
153 not covered }
1541100% url = self.uri.base + url;
155 not covered
1561100% if (data != null)
1571100% body = JSON.stringify(data);
158 not covered
1591100% request({ method: 'POST', uri: url, oauth: self.opts, form: data }, function (err, response, body) {
1601100% if (err)
1610 not covered return callback(err);
162 not covered
1631100% return callback(null, body);
164 not covered });
165 not covered };
166 not covered
1671100%module.exports = API;

lib/oauth.js

47% block coverage
67 SLOC
LineHitsStatementsSourceAction
11100%'use strict';
2 not covered
3 not covered //
4 not covered // Module: OAuth
5 not covered // =============
6 not covered //
7 not covered // Abstraction for the authentication methods of Twitter's API.
8 not covered //
9 not covered // **Notice**: At the moment this is depending on `request`'s ability to create OAuth
10 not covered // signatures, but in the future this should have it's own OAuth signing with
11 not covered // OAuth2 support.
12 not covered //
13 not covered // Methods
14 not covered // -------
15 not covered //
16 not covered // + [Constructor](#constructor)
17 not covered // + [Request Token](#requestToken)
18 not covered // + [Access Token](#accessToken)
19 not covered // + [Authenticate](#authenticate)
20 not covered // + [Authorize](#authorize)
21 not covered //
22 not covered // Usage
23 not covered // -----
24 not covered //
25 not covered // ```
26 not covered // var TwitterLib = require('twitter-rest-lite'),
27 not covered // oauth = new TwitterLib.OAuth(var_with_keys);
28 not covered //
29 not covered // api.requestToken(callback);
30 not covered //
31 not covered // api.accessToken(token, verifier, callback);
32 not covered //
33 not covered // api.authenticate(callback);
34 not covered //
35 not covered // api.authorize(callback);
36 not covered // ```
37 not covered //
38 not covered // <a name='constructor'></a>
39 not covered // Constructor
40 not covered // -----------
41 not covered //
42 not covered // #### Parameters
43 not covered //
44 not covered // + `uri` - Object with the basic API URI's
45 not covered // + `opts` - Object with the following params
46 not covered // - `consumer_key` - [Required] consumer_key from Twitter
47 not covered // - `consumer_secret` - [Required] consumer_secret from Twitter
48 not covered // - `callback` - [Optional]
49 not covered //
50 not covered // #### Returns
51 not covered //
52 not covered // An `Object` with methods `requestToken`, `accessToken`, `authenticate`
53 not covered // and `authorize`.
54 not covered //
55 not covered // #### Code
56 not covered function OAuth(uri, opts) {
575100% this.uri = uri;
58 not covered
59 not covered /* Extending `uri` with oauth URI's */
605100% this.uri.request_token = 'https://api.twitter.com/oauth/request_token';
615100% this.uri.access_token = 'https://api.twitter.com/oauth/access_token';
625100% this.uri.authenticate = 'https://api.twitter.com/oauth/authenticate';
635100% this.uri.authorize = 'https://api.twitter.com/oauth/authorize';
64 not covered
65 not covered /* checking the required arguments */
665100% ['consumer_key', 'consumer_secret'].forEach(function (item) {
6710100% if (opts[item] == null)
681100% throw new Error('There\'s a required argument missing: ' + item);
69 not covered });
70 not covered
714100% this.opts = opts;
72 not covered }
73 not covered
74 not covered //
75 not covered // <a name='requestToken'></a>
76 not covered // Public: get a request token
77 not covered // ---------------------------
78 not covered //
79 not covered // #### Parameters
80 not covered //
81 not covered // + `callback` - `Callback` Function
82 not covered //
83 not covered // #### Returns
84 not covered //
85 not covered // Returns a callback with an `Error Object` as first parameter if there was
86 not covered // (otherwise just `null`) and an `Object` with the response with the model:
87 not covered //
88 not covered // ```json
89 not covered // {
90 not covered // token: String,
91 not covered // token_secret: String,
92 not covered // oauth_callback_confirmed: Boolean
93 not covered // }
94 not covered // ```
95 not covered //
96 not covered // #### Example
97 not covered //
98 not covered // ```js
99 not covered // oauth.requestToken(function (err, response) {
100 not covered // if (err)
101 not covered // throw err;
102 not covered //
103 not covered // console.log(response);
104 not covered // });
105 not covered // ```
106 not covered //
107 not covered // `response.token` is used by [`oauth.authenticate`](#authenticate) and
108 not covered // [`oauth.authorize`](#authorize).
109 not covered //
110 not covered // #### Code
1111100%OAuth.prototype.requestToken = function(callback) {
1121100% var self = this;
1131100% var request = require('request');
1141100% var oauth = { consumer_key: self.opts.consumer_key, consumer_secret: self.opts.consumer_secret };
115 not covered consumer_key: self.opts.consumer_key,
1161100% if (self.opts.callback != null) {
1171100% oauth['callback'] = self.opts.callback;
118 not covered }
1191100% request({ method: 'POST', uri: self.uri.request_token, oauth: oauth }, function (err, response, body) {
1201100% if (err)
1210 not covered return callback(err);
122 not covered
1231100% if (response.statusCode !== 200) {
1240 not covered return callback(new Error(
125 not covered 'Twitter:OAuth.requestToken received an status differente than 200: \n' +
1260 not covered 'Status Code: ' + response.statusCode + '\n' +
1270 not covered 'Body: \n' + body
128 not covered ));
129 not covered }
130 not covered
1311100% var qs = require('querystring');
132 not covered
1331100% return callback(null, qs.parse(body));
134 not covered
135 not covered };
136 not covered
137 not covered //
138 not covered // <a name='accessToken'></a>
139 not covered // Public: get an access token
140 not covered // ---------------------------
141 not covered //
142 not covered // #### Parameters
143 not covered //
144 not covered // + `token` - `String` with `oauth_token`
145 not covered // + `verifier` - `String` with `oauth_verifier`
146 not covered // + `callback` - `Callback` Function
147 not covered //
148 not covered // #### Returns
149 not covered //
150 not covered // A `Callback` with an `Error` object as first parameter if there was
151 not covered // (otherwise just `null`) and an `Object` with the response with the model:
152 not covered //
153 not covered // ```js
154 not covered // {
155 not covered // oauth_token: String,
156 not covered // oauth_token_secret: String,
157 not covered // user_id: String,
158 not covered // screen_name: String
159 not covered // }
160 not covered // ```
161 not covered //
162 not covered // #### Example
163 not covered //
164 not covered // After running either `oauth.authenticate` or `oauth.authorize` and
165 not covered // making the proper request to twitter's servers you will end up with
166 not covered // a `token` and a `verifier`. Suppose they are stored each in a variable
167 not covered // of the same name, then:
168 not covered //
169 not covered // ```
170 not covered // oauth.accessToken(token, verifier, function (err, response) {
171 not covered // if (err)
172 not covered // throw (err);
173 not covered //
174 not covered // console.log(response);
175 not covered // });
176 not covered // ```
177 not covered //
178 not covered // With the data from that response you can initialize the API module and
179 not covered // start `GET`'ing and `POST`'ing with *user context* as Twitter calls it.
180 not covered //
181 not covered // #### Code
1821100%OAuth.prototype.accessToken = function(token, verifier, callback) {
1830 not covered var self = this;
1840 not covered var request = require('request');
185 not covered
1860 not covered [token, verifier].forEach(function (item) {
1870 not covered if (item == null) {
1880 not covered return callback(new Error(
189 not covered 'Twitter:OAuth.accessToken requires all the arguments to work.'
190 not covered }
191 not covered
1920 not covered var oauth = {
193 not covered
1940 not covered request({
1950 not covered if (err)
1960 not covered return callback(err);
197 not covered
1980 not covered var qs = require('querystring');
199 not covered
2000 not covered return callback(null, qs.parse(body));
201 not covered });
202 not covered
203 not covered
204 not covered //
205 not covered // <a name='authenticate'></a>
206 not covered // Public: get authenticate URL
207 not covered // ----------------------------
208 not covered //
209 not covered // #### Parameters
210 not covered //
211 not covered // + `token` - [Required] `String` with `oauth_token` from
212 not covered // `OAuth.requestToken`.
213 not covered // + `callback` - `Callback` Function
214 not covered //
215 not covered // #### Returns
216 not covered //
217 not covered // A `Callback` with an `Error` object as the first parameter and a `String`
218 not covered // with the URL to which redirect users as second parameter.
219 not covered //
220 not covered // #### Example
221 not covered //
222 not covered // ```js
223 not covered // oauth.authenticate(token, function (err, response) {
224 not covered // if (err)
225 not covered // throw err;
226 not covered //
227 not covered // console.log(response);
228 not covered // /* https://api.twitter.com/oauth/authenticate?oauth_token= + token provided */
229 not covered // });
230 not covered // ```
231 not covered //
232 not covered // #### Code
2331100%OAuth.prototype.authenticate = function(token, callback) {
2341100% var self = this;
235 not covered
2361100% if ((token == null) || (typeof token !== 'string')) {
2370 not covered return callback(new Error(
238 not covered 'Error: Twitter:OAuth.authenticate requires a token as first argument.'
2391100% return callback( null,
2401100% self.uri.authenticate + '?oauth_token=' + token
241 not covered );
242 not covered
243 not covered
244 not covered //
245 not covered // <a name='authorize'></a>
246 not covered // Public: get authorize URL
247 not covered // -------------------------
248 not covered //
249 not covered // #### Parameters
250 not covered //
251 not covered // + `token` - [Required] `String` with `oauth_token` from
252 not covered // `OAuth.requestToken`.
253 not covered // + `callback` - `Callback` Function
254 not covered //
255 not covered // #### Returns
256 not covered //
257 not covered // A `Callback` with an `Error` object as the first parameter and a `String`
258 not covered // with the URL to which redirect users as second parameter.
259 not covered //
260 not covered // #### Example
261 not covered //
262 not covered // ```js
263 not covered // oauth.authorize(token, function (err, response) {
264 not covered // if (err)
265 not covered // throw err;
266 not covered //
267 not covered // console.log(response);
268 not covered // /* https://api.twitter.com/oauth/authorize?oauth_token= + token provided */
269 not covered // });
270 not covered // ```
271 not covered // #### Code
2721100%OAuth.prototype.authorize = function(token, callback) {
2731100% var self = this;
274 not covered
2751100% if ((token == null) || (typeof token !== 'string')) {
2760 not covered return callback(new Error(
277 not covered 'Error: Twitter:OAuth.authorize requires a token as first argument.'
2781100% return callback( null,
2791100% self.uri.authorize + '?oauth_token=' + token
280 not covered );
281 not covered };
282 not covered
2831100%module.exports = OAuth;