UNPKG

@serptech/api

Version:

Library for work with SERP API

208 lines (168 loc) 5.64 kB
import { removeEmpty, isEmpty } from "./utils"; import qs from "qs"; import { HttpClientInterface } from "./serp-rest-api/api-facade/auth"; import sizeof from "object-sizeof"; import { getFormDataSize } from "./utils"; function getPayloadSize(payload: Record<string, unknown> | FormData): number { if (payload instanceof FormData) { return getFormDataSize(payload); } else { return sizeof(payload); } } const payloadIsTooLargeError = new Error("Payload is too large"); // 6mb const MAX_PAYLOAD_SIZE = 6291456; function prepareUrlParams(params: { q?: string }): Record<string, unknown> { const paramsWithValues = removeEmpty(params); if (Object.prototype.hasOwnProperty.call(params, "q")) { if (params.q === "") { delete paramsWithValues.q; } } return !isEmpty(paramsWithValues) ? paramsWithValues : {}; } type RequestData = FormData | Record<string, unknown>; type ResponseData = { data: Record<string, unknown> }; interface RequestClientInterface { defaults: { baseURL?: string; headers?: { Authorization?: string } }; get( url: string, config?: { params?: Record<string, unknown> } ): Promise<ResponseData>; post(url: string, data?: RequestData): Promise<ResponseData>; put(url: string, data?: RequestData): Promise<ResponseData>; delete( url: string, config?: { params?: Record<string, unknown>; data?: Record<string, unknown> | FormData; } ): Promise<ResponseData>; } interface RequestClientCreatorSettingsInterface { baseURL?: string; headers?: { "Content-Type": string; token?: string }; paramsSerializer?(params: any): string; } interface RequestClientCreatorInterface { create( settings: RequestClientCreatorSettingsInterface ): RequestClientInterface; } interface RequestClientCreatorSettingsInterface { baseURL?: string; token?: string; } function createHttpClient({ client, }: { client: RequestClientCreatorInterface; }): { new (settings: RequestClientCreatorSettingsInterface): HttpClientInterface; } { return class HttpClient implements HttpClientInterface { private client: RequestClientInterface; constructor({ baseURL, token }: RequestClientCreatorSettingsInterface) { Object.assign(this, { baseURL, token }); const headers: { "Content-Type": string; token?: string; } = { "Content-Type": "application/json", }; if (token) { headers.token = `Token ${token}`; } this.client = client.create({ baseURL, headers, paramsSerializer: function (params) { return qs.stringify(params, { arrayFormat: "comma" }); }, }); } setToken(token: string): void { if (token && this.client.defaults.headers) { this.client.defaults.headers["Authorization"] = `Token ${token}`; } } deleteToken(): void { if (this.client.defaults.headers) { delete this.client.defaults.headers["Authorization"]; } } setBaseURL(baseURL: string): void { if (baseURL) { this.client.defaults.baseURL = baseURL; } } post(url: string, data?: RequestData): Promise<Record<string, unknown>> { let preparedData = data; if (data && !(data instanceof FormData)) { preparedData = removeEmpty(data); } if (data && getPayloadSize(data) >= MAX_PAYLOAD_SIZE) { return Promise.reject(payloadIsTooLargeError); } if (preparedData) { return this.client.post(url, preparedData).then(({ data }) => data); } else { return this.client.post(url).then(({ data }) => data); } } get( url: string, params?: Record<string, unknown> ): Promise<Record<string, unknown>> { const config: { params?: Record<string, unknown> } = {}; if (params) { config.params = prepareUrlParams(params); } if (!isEmpty(config)) { return this.client.get(url, config).then(({ data }) => data); } else { return this.client.get(url).then(({ data }) => data); } } put(url: string, data?: RequestData): Promise<Record<string, unknown>> { let preparedData = data; if (data && !(data instanceof FormData)) { preparedData = removeEmpty(data); } if (data && getPayloadSize(data) >= MAX_PAYLOAD_SIZE) { return Promise.reject(payloadIsTooLargeError); } return this.client.put(url, preparedData).then(({ data }) => data); } delete( url: string, params?: Record<string, unknown>, data?: RequestData ): Promise<Record<string, unknown>> { const config: { params?: Record<string, unknown>; data?: Record<string, unknown> | FormData; } = {}; if (params) { config.params = prepareUrlParams(params); } let preparedData = data; if (data && !(data instanceof FormData)) { preparedData = removeEmpty(data); } if (preparedData) { config.data = preparedData; } if (data && getPayloadSize(data) >= MAX_PAYLOAD_SIZE) { return Promise.reject(payloadIsTooLargeError); } if (!isEmpty(config)) { return this.client.delete(url, config).then(({ data }) => data); } else { return this.client.delete(url).then(({ data }) => data); } } }; } export { createHttpClient };