Skip to content

Commit 2eba9ba

Browse files
authored
feat: migrate from deprecated request package to axios (#81)
* feat: migrate from deprecated request library to axios * remove unnecessary header check
1 parent 2c8fb83 commit 2eba9ba

File tree

7 files changed

+88
-110
lines changed

7 files changed

+88
-110
lines changed

.idea/workspace.xml

-74
This file was deleted.

package-lock.json

+50-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@
1010
"@oclif/errors": "^1.2.2",
1111
"@oclif/plugin-help": "^2.2.3",
1212
"@oclif/plugin-plugins": "^1.7.9",
13+
"axios": "^0.19.2",
1314
"chalk": "^2.4.2",
1415
"columnify": "^1.5.4",
1516
"fs-extra": "^7.0.1",
1617
"inquirer": "^6.5.2",
17-
"request": "^2.88.2",
18+
"qs": "^6.9.1",
1819
"semver": "^6.3.0",
1920
"shelljs": "^0.8.3",
2021
"tsv": "^0.2.0",

src/services/cli-http-client.js

+28-15
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1+
var http_ = require('http');
2+
var https = require('https');
13
const os = require('os');
24
const pkg = require('../../package.json');
5+
const qs = require('qs');
36
const { TwilioCliError } = require('../services/error');
47
const { NETWORK_ERROR } = require('../services/messaging/help-messages');
58

6-
const NETWORK_ERROR_CODES = new Set(['ETIMEDOUT', 'ESOCKETTIMEDOUT']);
9+
const NETWORK_ERROR_CODES = new Set(['ETIMEDOUT', 'ESOCKETTIMEDOUT', 'ECONNABORTED']);
710

811
class CliRequestClient {
912
constructor(commandName, logger, http) {
1013
this.commandName = commandName;
1114
this.logger = logger;
12-
this.http = require('util').promisify(http || require('request'));
15+
this.http = http || require('axios');
1316
}
1417

1518
/**
@@ -58,20 +61,26 @@ class CliRequestClient {
5861

5962
const options = {
6063
timeout: opts.timeout || 30000,
61-
followRedirect: opts.allowRedirects || false,
64+
maxRedirects: opts.allowRedirects ? 10 : 0,
6265
url: opts.uri,
6366
method: opts.method,
6467
headers,
65-
forever: opts.forever !== false
68+
httpAgent: opts.forever ? new http_.Agent({ keepAlive: true }) : undefined,
69+
httpsAgent: opts.forever ? new https.Agent({ keepAlive: true }) : undefined,
70+
validateStatus: status => {
71+
return status >= 100 && status < 600;
72+
}
6673
};
6774

6875
if (opts.data) {
69-
options.formData = opts.data;
76+
options.data = qs.stringify(opts.data, { arrayFormat: 'repeat' });
7077
}
7178

7279
if (opts.params) {
73-
options.qs = opts.params;
74-
options.useQuerystring = true;
80+
options.params = opts.params;
81+
options.paramSerializer = params => {
82+
return qs.stringify(params, { arrayFormat: 'repeat' });
83+
};
7584
}
7685

7786
this.lastRequest = options;
@@ -80,15 +89,19 @@ class CliRequestClient {
8089
try {
8190
const response = await this.http(options);
8291

83-
this.logger.debug('response.statusCode: ' + response.statusCode);
92+
this.logger.debug('response.statusCode: ' + response.status);
8493
this.logger.debug('response.headers: ' + JSON.stringify(response.headers));
8594

86-
if (response.statusCode < 200 || response.statusCode >= 300) {
87-
const parsed = JSON.parse(response.body);
95+
if (response.status < 200 || response.status >= 300) {
96+
const parsed = response.data;
8897
throw new TwilioCliError(`Error code ${parsed.code} from Twilio: ${parsed.message}. See ${parsed.more_info} for more info.`, parsed.code);
8998
}
9099

91-
return response;
100+
return {
101+
body: response.data,
102+
statusCode: response.status,
103+
headers: response.headers
104+
};
92105
} catch (error) {
93106
if (NETWORK_ERROR_CODES.has(error.code)) {
94107
throw new TwilioCliError(NETWORK_ERROR);
@@ -102,14 +115,14 @@ class CliRequestClient {
102115
this.logger.debug('-- BEGIN Twilio API Request --');
103116
this.logger.debug(options.method + ' ' + options.url);
104117

105-
if (options.formData) {
118+
if (options.data) {
106119
this.logger.debug('Form data:');
107-
this.logger.debug(options.formData);
120+
this.logger.debug(options.data);
108121
}
109122

110-
if (options.qs && Object.keys(options.qs).length > 0) {
123+
if (options.params && Object.keys(options.params).length > 0) {
111124
this.logger.debug('Querystring:');
112-
this.logger.debug(options.qs);
125+
this.logger.debug(options.params);
113126
}
114127

115128
this.logger.debug('User-Agent: ' + options.headers['User-Agent']);

src/services/open-api-client.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,7 @@ class OpenApiClient {
129129
}
130130

131131
convertBody(responseBody, schema) {
132-
const parsedBody = JSON.parse(responseBody);
133-
return this.converter.convertSchema(schema, parsedBody);
132+
return this.converter.convertSchema(schema, responseBody);
134133
}
135134

136135
evaluateRefs(schema, domain) {

test/services/cli-http-client.test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ describe('services', () => {
1010
});
1111

1212
test.it('should make an http request', async () => {
13-
const client = new CliRequestClient('blah', logger, (options, callback) => {
13+
const client = new CliRequestClient('blah', logger, options => {
1414
expect(options.url).to.equal('https://foo.com/bar');
15-
callback(null, { statusCode: 200, body: '{}' });
15+
return { status: 200, data: 'foo', headers: {} };
1616
});
1717
expect(client.commandName).to.equal('blah');
1818
const response = await client.request({
@@ -26,7 +26,7 @@ describe('services', () => {
2626
});
2727

2828
expect(response.statusCode).to.equal(200);
29-
expect(response.body).to.equal('{}');
29+
expect(response.body).to.equal('foo');
3030
});
3131

3232
test

test/services/twilio-api/twilio-client.test.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const { expect, test, constants } = require('@twilio/cli-test');
22
const { logger } = require('../../../src/services/messaging/logging');
33
const { TwilioApiClient } = require('../../../src/services/twilio-api');
44
const CliRequestClient = require('../../../src/services/cli-http-client');
5+
const qs = require('qs');
56

67
const accountSid = constants.FAKE_ACCOUNT_SID;
78
const callSid = 'CA12345678901234567890123456789012';
@@ -114,7 +115,7 @@ describe('services', () => {
114115
});
115116

116117
expect(response).to.eql({ status: 'ringing' });
117-
expect(httpClient.lastRequest.formData).to.eql({ To: '123', From: '456' });
118+
expect(httpClient.lastRequest.data).to.eql(qs.stringify({ To: '123', From: '456' }));
118119
});
119120

120121
test
@@ -148,7 +149,7 @@ describe('services', () => {
148149
});
149150

150151
expect(response).to.eql({ status: 'canceled' });
151-
expect(httpClient.lastRequest.formData).to.eql({ Status: 'canceled' });
152+
expect(httpClient.lastRequest.data).to.eql(qs.stringify({ Status: 'canceled' }));
152153
});
153154

154155
test
@@ -228,7 +229,7 @@ describe('services', () => {
228229
});
229230

230231
expect(response).to.eql({ verified: 'true' });
231-
expect(httpClient.lastRequest.formData).to.eql({ EmergencyEnabled: 'true' });
232+
expect(httpClient.lastRequest.data).to.eql(qs.stringify({ EmergencyEnabled: 'true' }));
232233
});
233234

234235
/* eslint-disable max-nested-callbacks */

0 commit comments

Comments
 (0)