Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: migrate from deprecated request module to axios #1058

Merged
merged 23 commits into from
Mar 24, 2020
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ rules:
consistent-this:
- error
- self
- _this
- $ctrl
quotes:
- error
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ clean:

install: clean
npm install
npx lerna bootstrap

test: install
yarn test:files
Expand Down
5 changes: 2 additions & 3 deletions packages/client/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@sendgrid/client",
"description": "Twilio SendGrid NodeJS API client",
"version": "6.5.5",
"version": "6.5.3",
eshanholtz marked this conversation as resolved.
Show resolved Hide resolved
"author": "Twilio SendGrid <dx@sendgrid.com> (sendgrid.com)",
"contributors": [
"Kyle Partridge <kyle.partridge@sendgrid.com>",
Expand All @@ -28,8 +28,7 @@
},
"dependencies": {
"@sendgrid/helpers": "^6.5.5",
"@types/request": "^2.48.4",
"request": "^2.88.0"
"axios": "^0.19.2"
},
"tags": [
"http",
Expand Down
67 changes: 37 additions & 30 deletions packages/client/src/classes/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
/**
* Dependencies
*/
const http = require('request');
const axios = require('axios');
const pkg = require('../../package.json');
const {
helpers: {
mergeData,
},
classes: {
Response,
eshanholtz marked this conversation as resolved.
Show resolved Hide resolved
ResponseError,
},
} = require('@sendgrid/helpers');
Expand All @@ -18,7 +19,6 @@ const {
* Twilio SendGrid REST Client
*/
class Client {

/**
* Constructor
*/
Expand All @@ -30,12 +30,12 @@ class Client {
//Default headers
this.defaultHeaders = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'User-agent': 'sendgrid/' + pkg.version + ';nodejs',
};

//Empty default request
this.defaultRequest = {
json: true,
baseUrl: 'https://api.sendgrid.com/',
url: '',
method: 'GET',
Expand Down Expand Up @@ -86,47 +86,54 @@ class Client {
/**
* Create request
*/
createRequest(data) {

//Keep URL parameter consistent
if (data.uri) {
data.url = data.uri;
delete data.uri;
}
createRequest(opts) {

let options = {
url: opts.uri || opts.url,
baseUrl: opts.baseUrl,
method: opts.method,
data: opts.body,
params: opts.qs,
headers: opts.headers,
};

//Merge data with empty request
const request = mergeData(this.defaultRequest, data);
options = mergeData(this.defaultRequest, options);
options.headers = this.createHeaders(options.headers);
options.baseURL = options.baseUrl;
delete options.baseUrl;

//Add headers
request.headers = this.createHeaders(request.headers);
return request;
return options;
}

/**
* Do a request
*/
request(data, cb) {
request(opts, cb) {

//Create request
const request = this.createRequest(data);
opts = this.createRequest(opts);

//Perform request
const promise = new Promise((resolve, reject) => {
http(request, (error, response, body) => {

//Request error
if (error) {
axios(opts)
.then(response => {
// Successful response
return resolve([
new Response(response.status, response.data, response.headers),
response.data,
]);
})
.catch(error => {
// Response error
if (error.response) {
if (error.response.status >= 400) {
return reject(new ResponseError(error.response));
}
}
// Request error
return reject(error);
}

//Response error
if (response.statusCode >= 400) {
return reject(new ResponseError(response));
}

//Successful response
resolve([response, body]);
});
});
});

// Throw and error incase function not passed
Expand Down
9 changes: 5 additions & 4 deletions packages/client/src/client.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {ResponseError} from "@sendgrid/helpers/classes";
import {ClientRequest} from "@sendgrid/client/src/request";
import {ClientRequest, RequestOptions} from "@sendgrid/client/src/request";
import {ClientResponse} from "@sendgrid/client/src/response";

declare class Client {
constructor();
/**
* Set API key
*/
Expand All @@ -16,7 +17,7 @@ declare class Client {
/**
* Set default request
*/
setDefaultRequest<K extends keyof ClientRequest>(key: K, value: ClientRequest[K]): this;
setDefaultRequest<K extends keyof RequestOptions>(key: K, value: RequestOptions[K]): this;

/**
* Create headers for request
Expand All @@ -26,12 +27,12 @@ declare class Client {
/**
* Create request
*/
createRequest(data: ClientRequest): ClientRequest;
createRequest<TData>(data: RequestOptions<TData>): ClientRequest;

/**
* Do a request
*/
request(data: ClientRequest, cb?: (err: ResponseError, response: [ClientResponse, any]) => void): Promise<[ClientResponse, any]>;
request<TData>(opts: RequestOptions<TData>, cb?: (err: ResponseError, response: [ClientResponse, any]) => void): Promise<[ClientResponse, any]>;
}

declare const client: Client & { Client: typeof Client };
Expand Down
5 changes: 3 additions & 2 deletions packages/client/src/request.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {OptionsWithUrl} from "request";
import {Request, RequestOptions} from "@sendgrid/helpers/classes/request";

export type ClientRequest = OptionsWithUrl;
export {Request as ClientRequest};
export {RequestOptions};
4 changes: 2 additions & 2 deletions packages/client/src/response.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import {RequestResponse} from "request";
import Response from "@sendgrid/helpers/classes/response";

export type ClientResponse = RequestResponse;
export type ClientResponse = Response;
6 changes: 5 additions & 1 deletion packages/helpers/classes/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import Attachment from "@sendgrid/helpers/classes/attachment";
import EmailAddress from "@sendgrid/helpers/classes/email-address";
import Mail from "@sendgrid/helpers/classes/mail"
import Personalization from "@sendgrid/helpers/classes/personalization";
import {Request} from "@sendgrid/helpers/classes/request";
import Response from "@sendgrid/helpers/classes/response";
eshanholtz marked this conversation as resolved.
Show resolved Hide resolved
import ResponseError from "@sendgrid/helpers/classes/response-error";

export {
Attachment,
EmailAddress,
Mail,
Personalization,
Request,
Response,
ResponseError,
}
}
2 changes: 2 additions & 0 deletions packages/helpers/classes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const Attachment = require('./attachment');
const EmailAddress = require('./email-address');
const Mail = require('./mail');
const Personalization = require('./personalization');
const Response = require('./response');
const ResponseError = require('./response-error');
const Statistics = require('./statistics');

Expand All @@ -18,6 +19,7 @@ module.exports = {
EmailAddress,
Mail,
Personalization,
Response,
ResponseError,
Statistics,
};
15 changes: 15 additions & 0 deletions packages/helpers/classes/request.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
type HttpMethod = 'get'|'GET'|'post'|'POST'|'put'|'PUT'|'patch'|'PATCH'|'delete'|'DELETE';

export interface RequestOptions<TData = any, TParams = object> {
method?: HttpMethod | '*';
url?: string;
auth?: string;
params?: TParams;
data?: TData | '*';
headers?: object | '*';
ca?: string;
eshanholtz marked this conversation as resolved.
Show resolved Hide resolved
}

export class Request<TData = any> {
eshanholtz marked this conversation as resolved.
Show resolved Hide resolved
constructor(opts: RequestOptions<TData>);
}
14 changes: 7 additions & 7 deletions packages/helpers/classes/response-error.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ class ResponseError extends Error {
super();

//Extract data from response
const {headers, statusCode, statusMessage, body} = response;
const {headers, status, statusText, data} = response;

//Set data
this.code = statusCode;
this.message = statusMessage;
this.response = {headers, body};
this.code = status;
this.message = statusText;
this.response = {headers, body: data};

//Capture stack trace
if (!this.stack) {
Expand All @@ -40,10 +40,10 @@ class ResponseError extends Error {
* Convert to string
*/
toString() {
const {body} = this.response;
const {data} = this.response;
eshanholtz marked this conversation as resolved.
Show resolved Hide resolved
let err = chalk.red(`${this.message} (${this.code})`);
if (body && Array.isArray(body.errors)) {
body.errors.forEach(error => {
if (data && Array.isArray(data.errors)) {
data.errors.forEach(error => {
const message = chalk.yellow(error.message);
const field = chalk.grey(error.field);
const help = chalk.grey(error.help);
Expand Down
7 changes: 7 additions & 0 deletions packages/helpers/classes/response.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default class Response<TPayload = object> {
statusCode: number;
body: TPayload;
headers: any;
constructor(statusCode: number, body: TPayload, headers?: any);
toString(): string;
}
15 changes: 15 additions & 0 deletions packages/helpers/classes/response.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

class Response {
constructor(statusCode, body, headers) {
this.statusCode = statusCode;
this.body = body;
this.headers = headers;
}

toString() {
return 'HTTP ' + this.statusCode + ' ' + this.body;
}
}

module.exports = Response;
6 changes: 2 additions & 4 deletions packages/helpers/helpers/merge-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ module.exports = function mergeData(base, data) {
if (data.hasOwnProperty(key)) {
if (data[key] && Array.isArray(data[key])) {
merged[key] = data[key];
}
else if (data[key] && typeof data[key] === 'object') {
} else if (data[key] && typeof data[key] === 'object') {
merged[key] = Object.assign({}, data[key]);
}
else {
} else if (data[key]) {
merged[key] = data[key];
}
}
Expand Down
4 changes: 2 additions & 2 deletions test/typescript/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ const req = Client.createRequest({
Client.request({
url: "/test"
}).then(res => {
res[0].headers
})
res[0].statusCode;
eshanholtz marked this conversation as resolved.
Show resolved Hide resolved
});