UNPKG

integration-websocket-rest-api

Version:

A JavaScript library for easy integration of REST API and WebSocket communication with state management in JS applications.

156 lines (133 loc) 4.7 kB
const axios = require("axios"); // const _ = require("lodash"); // const deepMapKeys = require("lodash-deep").deepMapKeys; const moment = require("moment"); const numeral = require("numeral"); class ApiClient { constructor(apiUrl, headers = {}) { this.apiUrl = apiUrl; this.headers = headers; this.maxRetries = 3; this.retryDelay = 1000; this.timeout = 5000; // Default timeout is 5 seconds this.errorHandler = null; this.requestInterceptors = []; this.responseInterceptors = []; // You can add more configuration options as needed } setGlobalHeaders(headers) { this.headers = { ...this.headers, ...headers }; } setMaxRetries(maxRetries) { this.maxRetries = maxRetries; } setRetryDelay(retryDelay) { this.retryDelay = retryDelay; } setTimeout(timeout) { this.timeout = timeout; } setErrorHandler(errorHandler) { this.errorHandler = errorHandler; } addRequestInterceptor(interceptor) { this.requestInterceptors.push(interceptor); } addResponseInterceptor(interceptor) { this.responseInterceptors.push(interceptor); } // Recursive function for deep mapping keys static deepMapKeys(obj, mapFn) { if (Array.isArray(obj)) { return obj.map((item) => ApiClient.deepMapKeys(item, mapFn)); } else if (typeof obj === "object" && obj !== null) { return Object.fromEntries( Object.entries(obj).map(([key, value]) => [ mapFn(value, key), ApiClient.deepMapKeys(value, mapFn), ]) ); } else { return obj; } } // Custom function to convert keys to camelCase static toCamelCase(key) { return key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()); } async sendRequest(method, data, retryCount = 0) { try { const config = { method, url: this.apiUrl, headers: this.headers, data, timeout: this.timeout, }; // Apply request interceptors this.requestInterceptors.forEach((interceptor) => interceptor(config)); const response = await axios(config); // Apply response interceptors const modifiedResponse = this.responseInterceptors.reduce( (resp, interceptor) => interceptor(resp), response ); // // Using lodash-deep to recursively format keys to camelCase // const formattedData = deepMapKeys(modifiedResponse.data, (value, key) => { // // Format date strings using moment.js // if (moment(value, moment.ISO_8601, true).isValid()) { // return moment(value).format("YYYY-MM-DD"); // } // // Format numbers using numeral.js // if (typeof value === "number") { // return numeral(value).format("0,0.00"); // } // // Default: camelCase for other keys // return _.camelCase(key); // }); // Using custom deepMapKeys to recursively format keys to camelCase const formattedData = ApiClient.deepMapKeys( modifiedResponse.data, (value, key) => { // Format date strings using moment.js if (moment(value, moment.ISO_8601, true).isValid()) { return moment(value).format("YYYY-MM-DD"); } // Format numbers using numeral.js if (typeof value === "number") { return numeral(value).format("0,0.00"); } // Default: camelCase for other keys return ApiClient.toCamelCase(key); } ); return formattedData; } catch (error) { if (retryCount < this.maxRetries) { console.log( `Retrying request. Attempt ${retryCount + 1} of ${this.maxRetries}` ); await new Promise((resolve) => setTimeout(resolve, this.retryDelay)); return this.sendRequest(method, data, retryCount + 1); } // Custom error handling if (this.errorHandler) { this.errorHandler(error); } // Handling errors with user-friendly messages and status codes if (error.response) { // The request was made, but the server responded with a status code outside the range of 2xx throw new Error( `API request failed with status ${error.response.status}: ${error.response.data}` ); } else if (error.request) { // The request was made but no response was received throw new Error(`API request failed: No response received`); } else { // Something happened in setting up the request that triggered an Error throw new Error(`API request setup failed: ${error.message}`); } } } } module.exports = ApiClient;