@@ -4,7 +4,7 @@ import * as _ from "lodash";
44import moment from 'moment' ;
55import qs from 'qs' ;
66import randomstring from 'randomstring' ;
7- import request from 'request' ;
7+ import Request from 'request/ request' ;
88import sha512 from 'crypto-js/sha512' ;
99
1010
@@ -14,11 +14,11 @@ import sha512 from 'crypto-js/sha512';
1414class CF {
1515
1616 /**
17- * Class constructor, It will Set default routes and options,
17+ * Class constructor, It will Set default routes and options
1818 */
1919 constructor ( ) {
2020
21- //credentials for api call
21+ //credentials for API call
2222 this . options = {
2323 API_URL : "http://codeforces.com/api" ,
2424 API_KEY : "" ,
@@ -63,10 +63,8 @@ class CF {
6363
6464
6565 /**
66- * Set api and api secret key for authenticate a API request.
67- *
68- * @param {string } API_KEY - user api key
69- * @param {string } API_SECRET - user api secret
66+ * @param {string } API_KEY - user API key
67+ * @param {string } API_SECRET - user API secret
7068 */
7169 setApis ( API_KEY = "" , API_SECRET = "" ) {
7270 this . options . API_KEY = API_KEY ;
@@ -75,75 +73,114 @@ class CF {
7573}
7674
7775
76+
7877/**
79- * Main HTTP request function.
8078 * About method and parameters, see official doc - http://codeforces.com/api/help/
8179 *
82- * @param {string } method - method of API request. [see doc]
83- * @param {object } params - API url parameters [see doc]
84- * @param {function } cb - callback function for async request
80+ * @param {string } method - method of API request.
81+ * @param {object } parameters - API url parameters
82+ * @param {function } callback
8583 * @returns {* }
8684 */
87- function callApi ( method , params , cb ) {
85+ function callApi ( method , parameters , callback ) {
86+
87+ if ( typeof parameters === 'undefined' ) {
88+ throw new Error ( 'undefined is not a valid parameters object.' ) ;
89+ }
90+
91+ if ( typeof parameters !== 'object' ) {
92+ throw new Error ( 'valid parameters object required.' ) ;
93+ }
8894
8995 let opts = this . options ;
9096
91- //validate api key
97+ let noCallback = ! callback || typeof callback !== 'function' ;
9298 let noApiKey = typeof opts . API_KEY !== 'string' || opts . API_KEY . length === 0 || typeof opts . API_SECRET !== 'string' || opts . API_SECRET . length === 0 ;
9399 if ( noApiKey ) {
94- return cb ( new Error ( "API key and API secret required.Please set before calling api." ) ) ;
100+ if ( noCallback ) {
101+ throw new Error ( 'API key and API secret required.' ) ;
102+ }
103+ return callback ( new Error ( "API key and API secret required." ) ) ;
95104 }
96105
97106 opts . method = method ;
98107
99- //final url of API request
100- let url = makeApiUrl ( opts , params ) ;
101-
108+ //target API url with hashes
109+ let url = makeApiUrl ( opts , parameters ) ;
102110
103- //request config
104- let requestConfig = {
111+ let reqOptions = {
105112 uri : url ,
106113 json : true ,
107114 timeout : process . env . CF_TIMEOUT || opts . DEFAULT_TIMEOUT
108115 } ;
109116
110- //return request for streaming, some data are so big
111- return request ( requestConfig , function ( err , httpResponse , body ) {
112- if ( err ) {
113- return cb ( err ) ;
114- }
117+ //callback not exists, just return the request modules Request class instance for event
118+ if ( noCallback ) {
119+ return new Request ( reqOptions ) ;
120+ }
115121
116- //API request failed
117- if ( body . status !== 'OK' ) {
118- return cb ( new Error ( body . comment ) ) ;
119- }
122+ //callback exists, return Request for streaming and handle callback for error handling and custom formatted data
123+ return callRequest ( reqOptions , handleCallback . bind ( null , callback ) ) ;
124+ }
125+
126+
127+ /**
128+ * Handle user callback
129+ *
130+ * @param callback - user callback
131+ * @param err - request errors
132+ * @param httpResponse - request HTTP response
133+ * @param body - request response body
134+ * @returns {* }
135+ */
136+ function handleCallback ( callback , err , httpResponse , body ) {
120137
121- return cb ( null , body . result ) ;
122- } ) ;
138+ if ( err ) {
139+ return callback ( err ) ;
140+ }
141+
142+ //API returns error
143+ if ( body . status !== 'OK' ) {
144+ return callback ( body . comment ) ;
145+ }
146+
147+ return callback ( null , body . result ) ;
148+ }
149+
150+
151+ /**
152+ * Call request modules main class instead of base function
153+ * @param options
154+ * @param callback
155+ * @returns {Request }
156+ */
157+ function callRequest ( options , callback ) {
158+ options . callback = callback ;
159+ return new Request ( options ) ;
123160}
124161
125162
126163/**
127164 * Generate API url according to CF API rules
128165 *
129166 * @param {array } options - main class options
130- * @param {array } params - API url parameters [see doc]
167+ * @param {array } parameters - API url parameters [see doc]
131168 * @returns {string } - final url
132169 */
133- function makeApiUrl ( options , params ) {
170+ function makeApiUrl ( options , parameters ) {
134171
135172 //main query to add in API url request
136- let query = params ;
173+ let query = parameters ;
137174 let curTime = moment ( ) . unix ( ) ;
138175 let randomToken = randomstring . generate ( 6 ) ;
139176
140177 query . time = curTime ;
141178 query . apiKey = options . API_KEY ;
142179
143180 //if any parameter given as array, make it string separated by semicolon(;)
144- for ( let key in params ) {
145- if ( _ . isArray ( params [ key ] ) ) {
146- params [ key ] = _ . join ( params [ key ] , ';' ) ;
181+ for ( let key in parameters ) {
182+ if ( _ . isArray ( parameters [ key ] ) ) {
183+ parameters [ key ] = _ . join ( parameters [ key ] , ';' ) ;
147184 }
148185 }
149186
0 commit comments