Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@aircall/http

Package Overview
Dependencies
Maintainers
8
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aircall/http - npm Package Compare versions

Comparing version 0.1.3 to 0.1.4

12

CHANGELOG.md

@@ -6,2 +6,14 @@ # Change Log

## [0.1.4](http://bitbucket.org/aircall/front-end-modules/compare/@aircall/http@0.1.3...@aircall/http@0.1.4) (2020-04-09)
### Bug Fixes
* prettify ([a4f45d6](http://bitbucket.org/aircall/front-end-modules/commits/a4f45d68053b300f8a5ba933242d7d44b2bda6fd))
* **http:** use logger singleton consumer instance ([583f2b3](http://bitbucket.org/aircall/front-end-modules/commits/583f2b39d2784bf459e1b6cea06149fc4f645afc))
## [0.1.3](http://bitbucket.org/aircall/front-end-modules/compare/@aircall/http@0.1.2...@aircall/http@0.1.3) (2020-04-02)

@@ -8,0 +20,0 @@

5

dist/HttpService.d.ts

@@ -1,3 +0,3 @@

import { AxiosError, AxiosPromise, AxiosRequestConfig } from "axios";
import { HttpServiceOptions, RequestLogPayload, SearchParams, HTTP_LOG_TYPE } from "./typing/HttpService";
import { AxiosError, AxiosPromise, AxiosRequestConfig } from 'axios';
import { HttpServiceOptions, RequestLogPayload, SearchParams, HTTP_LOG_TYPE } from './typing/HttpService';
declare class HttpService {

@@ -7,2 +7,3 @@ private options;

private axiosInstance;
private logger;
private axiosExternalInstance;

@@ -9,0 +10,0 @@ constructor(options: HttpServiceOptions);

31

dist/HttpService.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const logger_1 = require("@aircall/logger");
const axios_1 = require("axios");

@@ -24,3 +23,3 @@ const constants_1 = require("./constants");

this.getUrlFromConfig = (baseURL, url, httpLogType) => {
if (!url || !baseURL || httpLogType === "REQUEST") {
if (!url || !baseURL || httpLogType === 'REQUEST') {
return url;

@@ -30,3 +29,3 @@ }

// meanwhile request.config.url is only the path
return url.replace(`${baseURL}/`, "");
return url.replace(`${baseURL}/`, '');
};

@@ -37,3 +36,3 @@ /**

this.logRequestInterceptor = (config) => {
logger_1.default.info(`HTTP | ${config.method} | REQUEST`.toUpperCase(), {
this.logger.info(`HTTP | ${config.method} | REQUEST`.toUpperCase(), {
request: HttpService.getRequestLogPayload(config)

@@ -47,3 +46,3 @@ });

this.logResponseInterceptor = (response) => {
logger_1.default.debug(`HTTP | ${response.config.method} | SUCCESS`.toUpperCase(), {
this.logger.debug(`HTTP | ${response.config.method} | SUCCESS`.toUpperCase(), {
request: HttpService.getRequestLogPayload(response.config),

@@ -60,3 +59,3 @@ response: { response_code: response.status }

(_b = (_a = this.options).logErrorInterceptor) === null || _b === void 0 ? void 0 : _b.call(_a, error);
logger_1.default.error(`HTTP | ${error.config.method} | ERROR`.toUpperCase(), {
this.logger.error(`HTTP | ${error.config.method} | ERROR`.toUpperCase(), {
request: HttpService.getRequestLogPayload(error.config),

@@ -94,6 +93,10 @@ response: { error }

};
if (!this.options.apiBaseUrl) {
throw new Error("Missing API URL!");
const { apiBaseUrl, logger } = this.options;
if (!apiBaseUrl) {
throw new Error('Missing API URL!');
}
const { apiBaseUrl } = this.options;
if (!logger) {
throw new Error('Missing Logger instance!');
}
this.logger = logger;
/**

@@ -105,4 +108,4 @@ * Create an axios instance with the API base URL

headers: {
"Content-Type": "application/json; charset=UTF-8",
Accept: "application/json, text/plain, */*"
'Content-Type': 'application/json; charset=UTF-8',
Accept: 'application/json, text/plain, */*'
}

@@ -132,6 +135,4 @@ }));

? Object.keys(searchParams)
.map(key => encodeURIComponent(key) +
"=" +
encodeURIComponent(searchParams[key]))
.join("&")
.map(key => encodeURIComponent(key) + '=' + encodeURIComponent(searchParams[key]))
.join('&')
: undefined;

@@ -138,0 +139,0 @@ return queryString ? `${path}?${queryString}` : path;

@@ -1,2 +0,3 @@

import { AxiosRequestConfig, AxiosError } from "axios";
import { AxiosRequestConfig, AxiosError } from 'axios';
import { Logger } from '@aircall/logger';
export interface ApiError {

@@ -19,7 +20,8 @@ data: Record<string, string[]>;

export declare type SearchParams = Record<string, Primitive | Primitive[] | null | undefined>;
export declare type HTTP_LOG_TYPE = "REQUEST" | "SUCCESS" | "ERROR";
export declare type HTTP_LOG_TYPE = 'REQUEST' | 'SUCCESS' | 'ERROR';
export interface HttpServiceOptions {
apiBaseUrl?: string;
logger?: Logger;
logErrorInterceptor?: (error: AxiosError) => Promise<AxiosError> | void;
}
export {};
{
"name": "@aircall/http",
"version": "0.1.3",
"version": "0.1.4",
"main": "dist/index.js",

@@ -14,5 +14,5 @@ "types": "dist/index.d.ts",

},
"gitHead": "b78b28cbf565454ebe6f37580f3f8df9609bc857",
"gitHead": "6574e120a8b34fe9032587850a0aa3f775c2c808",
"dependencies": {
"@aircall/logger": "^2.3.3",
"@aircall/logger": "^2.3.4",
"axios": "0.19.2"

@@ -19,0 +19,0 @@ },

@@ -5,5 +5,5 @@ export enum ErrorCode {

// Rails response when user locked
UNAUTHORIZED_API_RESPONSE_CODE = 401,
UNAUTHORIZED_API_RESPONSE_CODE = 401
}
export const INVALID_API_RESPONSE_MESSAGE = 'An internal error occured';
import axios, { AxiosError } from 'axios';
import MockAdapter from 'axios-mock-adapter';
import {
ErrorCode,
INVALID_API_RESPONSE_MESSAGE,
} from './constants';
import { Logger } from '@aircall/logger';
import { ErrorCode, INVALID_API_RESPONSE_MESSAGE } from './constants';
import HttpService from './';
const logger = new Logger();
describe('HttpService', () => {

@@ -19,3 +19,3 @@ let httpService: HttpService;

mock = new MockAdapter(axios);
httpService = new HttpService({ apiBaseUrl: BASE_URL});
httpService = new HttpService({ apiBaseUrl: BASE_URL, logger });
httpService.setToken('foobar');

@@ -27,3 +27,3 @@ });

try {
httpService = new HttpService({ apiBaseUrl: undefined});
httpService = new HttpService({ apiBaseUrl: undefined, logger });
} catch (e) {

@@ -33,2 +33,10 @@ expect(e.message).toBe('Missing API URL!');

});
it('should throw an error if the class is instantiated without logger', async () => {
try {
httpService = new HttpService({ apiBaseUrl: BASE_URL, logger: undefined });
} catch (e) {
expect(e.message).toBe('Missing Logger instance!');
}
});
});

@@ -132,3 +140,3 @@

});
it('should call axios with PUT verb', async () => {

@@ -197,3 +205,5 @@ const payload = {

// @ts-ignore
expect(httpService.getFirstErrorMessageOnFirstField({ data: { fieldName: null } })).toEqual(null);
expect(httpService.getFirstErrorMessageOnFirstField({ data: { fieldName: null } })).toEqual(
null
);
});

@@ -203,3 +213,5 @@

// @ts-ignore
expect(httpService.getFirstErrorMessageOnFirstField({ data: { fieldName: [] } })).toEqual(null);
expect(httpService.getFirstErrorMessageOnFirstField({ data: { fieldName: [] } })).toEqual(
null
);
});

@@ -283,3 +295,6 @@

httpService.handleError({
response: { status: ErrorCode.UNAUTHORIZED_API_RESPONSE_CODE, data: 'Error from the server' }
response: {
status: ErrorCode.UNAUTHORIZED_API_RESPONSE_CODE,
data: 'Error from the server'
}
} as AxiosError);

@@ -334,5 +349,5 @@ } catch (e) {

it('should call logErrorInterceptor if proviced', (done) => {
it('should call logErrorInterceptor if proviced', done => {
const logErrorInterceptor = jest.fn();
const service = new HttpService({ apiBaseUrl: BASE_URL , logErrorInterceptor });
const service = new HttpService({ apiBaseUrl: BASE_URL, logErrorInterceptor, logger });
const error = { config: { method: 'get' } } as AxiosError;

@@ -339,0 +354,0 @@

@@ -1,2 +0,1 @@

import logger from "@aircall/logger";
import axios, {

@@ -8,11 +7,15 @@ AxiosError,

AxiosResponse
} from "axios";
} from 'axios';
import { Logger } from '@aircall/logger';
import { ErrorCode, INVALID_API_RESPONSE_MESSAGE } from './constants';
import {
ErrorCode,
INVALID_API_RESPONSE_MESSAGE
} from "./constants";
import { ApiResponseError, HttpServiceOptions, RequestLogPayload, SearchParams, ApiError, HTTP_LOG_TYPE } from "./typing/HttpService";
ApiResponseError,
HttpServiceOptions,
RequestLogPayload,
SearchParams,
ApiError,
HTTP_LOG_TYPE
} from './typing/HttpService';
// Fallback for unsupported error response

@@ -27,10 +30,17 @@ const defaultInvalidApiResponseErr: ApiResponseError = {

private axiosInstance: AxiosInstance;
private logger: Logger;
private axiosExternalInstance: AxiosInstance;
public constructor(private options: HttpServiceOptions) {
if (!this.options.apiBaseUrl) {
throw new Error("Missing API URL!");
const { apiBaseUrl, logger } = this.options;
if (!apiBaseUrl) {
throw new Error('Missing API URL!');
}
const { apiBaseUrl } = this.options;
if (!logger) {
throw new Error('Missing Logger instance!');
}
this.logger = logger;
/**

@@ -43,4 +53,4 @@ * Create an axios instance with the API base URL

headers: {
"Content-Type": "application/json; charset=UTF-8",
Accept: "application/json, text/plain, */*"
'Content-Type': 'application/json; charset=UTF-8',
Accept: 'application/json, text/plain, */*'
}

@@ -59,5 +69,3 @@ })

this.axiosExternalInstance = axios.create();
this.axiosExternalInstance.interceptors.request.use(
this.logRequestInterceptor
);
this.axiosExternalInstance.interceptors.request.use(this.logRequestInterceptor);
this.axiosExternalInstance.interceptors.response.use(

@@ -102,3 +110,3 @@ this.logResponseInterceptor,

): string | undefined => {
if (!url || !baseURL || httpLogType === "REQUEST") {
if (!url || !baseURL || httpLogType === 'REQUEST') {
return url;

@@ -109,3 +117,3 @@ }

// meanwhile request.config.url is only the path
return url.replace(`${baseURL}/`, "");
return url.replace(`${baseURL}/`, '');
};

@@ -128,3 +136,3 @@

private logRequestInterceptor = (config: AxiosRequestConfig): AxiosRequestConfig => {
logger.info(`HTTP | ${config.method} | REQUEST`.toUpperCase(), {
this.logger.info(`HTTP | ${config.method} | REQUEST`.toUpperCase(), {
request: HttpService.getRequestLogPayload(config)

@@ -140,3 +148,3 @@ });

private logResponseInterceptor = (response: AxiosResponse): AxiosResponse => {
logger.debug(`HTTP | ${response.config.method} | SUCCESS`.toUpperCase(), {
this.logger.debug(`HTTP | ${response.config.method} | SUCCESS`.toUpperCase(), {
request: HttpService.getRequestLogPayload(response.config),

@@ -152,9 +160,6 @@ response: { response_code: response.status }

*/
public logErrorInterceptor = (
error: AxiosError
): Promise<AxiosError> => {
public logErrorInterceptor = (error: AxiosError): Promise<AxiosError> => {
this.options.logErrorInterceptor?.(error);
logger.error(`HTTP | ${error.config.method} | ERROR`.toUpperCase(), {
this.logger.error(`HTTP | ${error.config.method} | ERROR`.toUpperCase(), {
request: HttpService.getRequestLogPayload(error.config),

@@ -176,5 +181,3 @@ response: { error }

// that falls out of the range of 2xx
const errorMessage: string | null = this.getFirstErrorMessageOnFirstField(
error.response
);
const errorMessage: string | null = this.getFirstErrorMessageOnFirstField(error.response);
err = {

@@ -206,9 +209,6 @@ code: error.response.status || ErrorCode.INVALID_API_RESPONSE_CODE,

? Object.keys(searchParams)
.map(
key =>
encodeURIComponent(key) +
"=" +
encodeURIComponent(searchParams[key] as string)
)
.join("&")
.map(
key => encodeURIComponent(key) + '=' + encodeURIComponent(searchParams[key] as string)
)
.join('&')
: undefined;

@@ -218,6 +218,3 @@ return queryString ? `${path}?${queryString}` : path;

public get(
path: string,
searchParams?: SearchParams
): AxiosPromise<object> {
public get(path: string, searchParams?: SearchParams): AxiosPromise<object> {
return this.axiosInstance

@@ -233,7 +230,3 @@ .get(path, {

public post(
path: string,
payload: {} = {},
searchParams?: SearchParams
): AxiosPromise<object> {
public post(path: string, payload: {} = {}, searchParams?: SearchParams): AxiosPromise<object> {
return this.axiosInstance

@@ -256,7 +249,3 @@ .post(this.getPathWithParams(path, searchParams), { ...payload })

public patch(
path: string,
payload: {} = {},
searchParams?: SearchParams
): Promise<object> {
public patch(path: string, payload: {} = {}, searchParams?: SearchParams): Promise<object> {
return this.axiosInstance

@@ -270,7 +259,3 @@ .patch(this.getPathWithParams(path, searchParams), {

public put(
path: string,
payload: {} = {},
searchParams?: SearchParams
): Promise<object> {
public put(path: string, payload: {} = {}, searchParams?: SearchParams): Promise<object> {
return this.axiosInstance

@@ -284,7 +269,3 @@ .put(this.getPathWithParams(path, searchParams), {

public delete(
path: string,
payload: {} = {},
searchParams?: SearchParams
): Promise<object> {
public delete(path: string, payload: {} = {}, searchParams?: SearchParams): Promise<object> {
return this.axiosInstance

@@ -306,5 +287,3 @@ .delete(this.getPathWithParams(path, searchParams), {

*/
private getFirstErrorMessageOnFirstField(
errorResponse: ApiError
): string | null {
private getFirstErrorMessageOnFirstField(errorResponse: ApiError): string | null {
if (!errorResponse || !errorResponse.data) {

@@ -325,3 +304,2 @@ // No "body.error"

export default HttpService;

@@ -1,2 +0,3 @@

import { AxiosRequestConfig, AxiosError } from "axios";
import { AxiosRequestConfig, AxiosError } from 'axios';
import { Logger } from '@aircall/logger';

@@ -25,9 +26,8 @@ // Rails error response

export type HTTP_LOG_TYPE = "REQUEST" | "SUCCESS" | "ERROR";
export type HTTP_LOG_TYPE = 'REQUEST' | 'SUCCESS' | 'ERROR';
export interface HttpServiceOptions {
apiBaseUrl?: string;
logErrorInterceptor?: (
error: AxiosError
) => Promise<AxiosError> | void;
logger?: Logger;
logErrorInterceptor?: (error: AxiosError) => Promise<AxiosError> | void;
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc