UNPKG

@multiversx/sdk-nestjs-http

Version:
311 lines 12.4 kB
"use strict"; var ApiService_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.ApiService = void 0; const tslib_1 = require("tslib"); const common_1 = require("@nestjs/common"); const axios_1 = tslib_1.__importDefault(require("axios")); const agentkeepalive_1 = tslib_1.__importDefault(require("agentkeepalive")); const sdk_nestjs_monitoring_1 = require("@multiversx/sdk-nestjs-monitoring"); const api_settings_1 = require("./entities/api.settings"); const api_module_options_1 = require("./entities/api.module.options"); const sdk_nestjs_common_1 = require("@multiversx/sdk-nestjs-common"); let ApiService = class ApiService { static { ApiService_1 = this; } options; metricsService; defaultTimeout = 30000; keepaliveAgent = null; axiosInstance; static concurrentRequests = 0; constructor(options, metricsService) { this.options = options; this.metricsService = metricsService; this.axiosInstance = axios_1.default.create({ httpAgent: this.getKeepAliveAgent(), transformResponse: [ (data) => { try { return JSON.parse(data); } catch (error) { return data; } }, ], }); if (options.logConnectionKeepAlive) { const logger = new common_1.Logger(ApiService_1.name); this.axiosInstance.interceptors.request.use(request => { logger.log(`URL: ${request.url}, Request Headers: ${request.headers['connection'] ?? 'Not set'}`); return request; }); this.axiosInstance.interceptors.response.use(response => { logger.log(`URL: ${response.config?.url}, Response Headers: ${response.headers['connection'] ?? 'Not set'}`); return response; }); } } getKeepAliveAgent() { if (this.keepaliveAgent === null) { if (this.options.useKeepAliveAgent) { this.keepaliveAgent = new agentkeepalive_1.default({ keepAlive: true, maxSockets: Infinity, maxFreeSockets: this.options.keepAliveMaxFreeSockets ?? 10, timeout: this.options.axiosTimeout, freeSocketTimeout: this.options.keepAliveFreeSocketTimeout ?? 30000, }); } else { this.keepaliveAgent = undefined; } } return this.keepaliveAgent; } async getConfig(settings) { const timeout = settings.timeout || this.defaultTimeout; const maxRedirects = settings.skipRedirects === true ? 0 : undefined; const headers = settings.headers ?? {}; if (this.options.useKeepAliveHeader) { headers['connection'] = 'keep-alive'; } const rateLimiterSecret = this.options.rateLimiterSecret; if (rateLimiterSecret) { headers['x-rate-limiter-secret'] = rateLimiterSecret; } if (settings.nativeAuthSigner) { const accessTokenInfo = await settings.nativeAuthSigner.getToken(); headers['authorization'] = `Bearer ${accessTokenInfo.token}`; } const context = sdk_nestjs_common_1.ContextTracker.get(); if (context && context.requestId) { headers['x-request-id'] = context.requestId; } const config = { timeout, maxRedirects, httpsAgent: settings.httpsAgent, responseType: settings.responseType, auth: settings.auth, params: settings.params, headers, }; if (settings.validateStatus) { config.validateStatus = settings.validateStatus; } return config; } requestsExecuter = new sdk_nestjs_common_1.PendingExecuter(); incrementConcurrentRequests(url) { ApiService_1.concurrentRequests++; this.metricsService.setApiConcurrentRequests(url, ApiService_1.concurrentRequests); } decrementConcurrentRequests(url) { ApiService_1.concurrentRequests--; this.metricsService.setApiConcurrentRequests(url, ApiService_1.concurrentRequests); } async get(url, settings = new api_settings_1.ApiSettings(), errorHandler) { const profiler = new sdk_nestjs_monitoring_1.PerformanceProfiler(); const config = await this.getConfig(settings); const hostName = this.getHostname(url); this.incrementConcurrentRequests(hostName); try { if (config.auth || config.headers?.Authorization || config.headers?.authorization) { return await this.axiosInstance.get(url, config); } const urlKey = config.params ? `${url}?${JSON.stringify(config.params)}` : url; return await this.requestsExecuter.execute(urlKey, async () => await this.axiosInstance.get(url, config)); } catch (error) { let handled = false; if (errorHandler) { handled = await errorHandler(error); } if (!handled) { const customError = this.getCustomError('GET', url, null, error); const logger = new common_1.Logger(ApiService_1.name); logger.error(customError); throw customError; } } finally { profiler.stop(); this.metricsService.setExternalCall(hostName, profiler.duration); this.decrementConcurrentRequests(hostName); } } async put(url, data, settings = new api_settings_1.ApiSettings(), errorHandler) { const profiler = new sdk_nestjs_monitoring_1.PerformanceProfiler(); const config = await this.getConfig(settings); const hostName = this.getHostname(url); this.incrementConcurrentRequests(hostName); try { return await this.axiosInstance.put(url, data, config); } catch (error) { let handled = false; if (errorHandler) { handled = await errorHandler(error); } if (!handled) { const logger = new common_1.Logger(ApiService_1.name); const customError = { method: 'PUT', url, response: error.response?.data, status: error.response?.status, message: error.message, name: error.name, }; logger.error(customError); throw customError; } } finally { profiler.stop(); this.metricsService.setExternalCall(hostName, profiler.duration); this.decrementConcurrentRequests(hostName); } } async patch(url, data, settings = new api_settings_1.ApiSettings(), errorHandler) { const profiler = new sdk_nestjs_monitoring_1.PerformanceProfiler(); const config = await this.getConfig(settings); const hostName = this.getHostname(url); this.incrementConcurrentRequests(hostName); try { return await this.axiosInstance.patch(url, data, config); } catch (error) { let handled = false; if (errorHandler) { handled = await errorHandler(error); } if (!handled) { const logger = new common_1.Logger(ApiService_1.name); const customError = { method: 'PATCH', url, response: error.response?.data, status: error.response?.status, message: error.message, name: error.name, }; logger.error(customError); throw customError; } } finally { profiler.stop(); this.metricsService.setExternalCall(hostName, profiler.duration); this.decrementConcurrentRequests(hostName); } } async post(url, data, settings = new api_settings_1.ApiSettings(), errorHandler) { const profiler = new sdk_nestjs_monitoring_1.PerformanceProfiler(); const config = await this.getConfig(settings); const hostName = this.getHostname(url); this.incrementConcurrentRequests(hostName); try { const response = await this.axiosInstance.post(url, data, config); return response; } catch (error) { let handled = false; if (errorHandler) { handled = await errorHandler(error); } if (!handled) { const customError = this.getCustomError('POST', url, data, error); const logger = new common_1.Logger(ApiService_1.name); logger.error(customError); throw customError; } } finally { profiler.stop(); this.metricsService.setExternalCall(hostName, profiler.duration); this.decrementConcurrentRequests(hostName); } } async delete(url, data, settings = new api_settings_1.ApiSettings(), errorHandler) { const profiler = new sdk_nestjs_monitoring_1.PerformanceProfiler(); const config = await this.getConfig(settings); const hostName = this.getHostname(url); this.incrementConcurrentRequests(hostName); try { const response = await this.axiosInstance.delete(url, { data, ...config, }); return response; } catch (error) { let handled = false; if (errorHandler) { handled = await errorHandler(error); } if (!handled) { const customError = this.getCustomError('DELETE', url, data, error); const logger = new common_1.Logger(ApiService_1.name); logger.error(customError); throw customError; } } finally { profiler.stop(); this.metricsService.setExternalCall(hostName, profiler.duration); this.decrementConcurrentRequests(hostName); } } async head(url, settings = new api_settings_1.ApiSettings(), errorHandler) { const profiler = new sdk_nestjs_monitoring_1.PerformanceProfiler(); const config = await this.getConfig(settings); const hostName = this.getHostname(url); this.incrementConcurrentRequests(hostName); try { const response = await this.axiosInstance.head(url, config); return response; } catch (error) { let handled = false; if (errorHandler) { handled = await errorHandler(error); } if (!handled) { const customError = this.getCustomError('HEAD', url, null, error); const logger = new common_1.Logger(ApiService_1.name); logger.error(customError); throw customError; } } finally { profiler.stop(); this.metricsService.setExternalCall(hostName, profiler.duration); this.decrementConcurrentRequests(hostName); } } getHostname(url) { return new URL(url).hostname; } getCustomError(method, url, data, error) { return { method, url, body: data, response: error.response?.data, status: error.response?.status, message: error.message, name: error.name, stack: error.stack, }; } }; exports.ApiService = ApiService; exports.ApiService = ApiService = ApiService_1 = tslib_1.__decorate([ (0, common_1.Injectable)(), tslib_1.__param(1, (0, common_1.Inject)((0, common_1.forwardRef)(() => sdk_nestjs_monitoring_1.MetricsService))), tslib_1.__metadata("design:paramtypes", [api_module_options_1.ApiModuleOptions, sdk_nestjs_monitoring_1.MetricsService]) ], ApiService); //# sourceMappingURL=api.service.js.map