UNPKG

@multiversx/sdk-nestjs-http

Version:
301 lines 12.6 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 = ApiService_1 = class ApiService { constructor(options, metricsService) { this.options = options; this.metricsService = metricsService; this.defaultTimeout = 30000; this.keepaliveAgent = null; this.requestsExecuter = new sdk_nestjs_common_1.PendingExecuter(); 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 => { var _a; logger.log(`URL: ${request.url}, Request Headers: ${(_a = request.headers['connection']) !== null && _a !== void 0 ? _a : 'Not set'}`); return request; }); this.axiosInstance.interceptors.response.use(response => { var _a, _b; logger.log(`URL: ${(_a = response.config) === null || _a === void 0 ? void 0 : _a.url}, Response Headers: ${(_b = response.headers['connection']) !== null && _b !== void 0 ? _b : 'Not set'}`); return response; }); } } getKeepAliveAgent() { var _a, _b; if (this.keepaliveAgent === null) { if (this.options.useKeepAliveAgent) { this.keepaliveAgent = new agentkeepalive_1.default({ keepAlive: true, maxSockets: Infinity, maxFreeSockets: (_a = this.options.keepAliveMaxFreeSockets) !== null && _a !== void 0 ? _a : 10, timeout: this.options.axiosTimeout, freeSocketTimeout: (_b = this.options.keepAliveFreeSocketTimeout) !== null && _b !== void 0 ? _b : 30000, }); } else { this.keepaliveAgent = undefined; } } return this.keepaliveAgent; } async getConfig(settings) { var _a; const timeout = settings.timeout || this.defaultTimeout; const maxRedirects = settings.skipRedirects === true ? 0 : undefined; const headers = (_a = settings.headers) !== null && _a !== void 0 ? _a : {}; 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; } 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); this.incrementConcurrentRequests(this.getHostname(url)); try { return await this.requestsExecuter.execute(url, 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(this.getHostname(url), profiler.duration); this.decrementConcurrentRequests(this.getHostname(url)); } } async put(url, data, settings = new api_settings_1.ApiSettings(), errorHandler) { var _a, _b; const profiler = new sdk_nestjs_monitoring_1.PerformanceProfiler(); const config = await this.getConfig(settings); this.incrementConcurrentRequests(this.getHostname(url)); 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: (_a = error.response) === null || _a === void 0 ? void 0 : _a.data, status: (_b = error.response) === null || _b === void 0 ? void 0 : _b.status, message: error.message, name: error.name, }; logger.error(customError); throw customError; } } finally { profiler.stop(); this.metricsService.setExternalCall(this.getHostname(url), profiler.duration); this.decrementConcurrentRequests(this.getHostname(url)); } } async patch(url, data, settings = new api_settings_1.ApiSettings(), errorHandler) { var _a, _b; const profiler = new sdk_nestjs_monitoring_1.PerformanceProfiler(); const config = await this.getConfig(settings); this.incrementConcurrentRequests(this.getHostname(url)); 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: (_a = error.response) === null || _a === void 0 ? void 0 : _a.data, status: (_b = error.response) === null || _b === void 0 ? void 0 : _b.status, message: error.message, name: error.name, }; logger.error(customError); throw customError; } } finally { profiler.stop(); this.metricsService.setExternalCall(this.getHostname(url), profiler.duration); this.decrementConcurrentRequests(this.getHostname(url)); } } 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); this.incrementConcurrentRequests(this.getHostname(url)); 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(this.getHostname(url), profiler.duration); this.decrementConcurrentRequests(this.getHostname(url)); } } 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); this.incrementConcurrentRequests(this.getHostname(url)); try { const response = await this.axiosInstance.delete(url, Object.assign({ 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(this.getHostname(url), profiler.duration); this.decrementConcurrentRequests(this.getHostname(url)); } } async head(url, settings = new api_settings_1.ApiSettings(), errorHandler) { const profiler = new sdk_nestjs_monitoring_1.PerformanceProfiler(); const config = await this.getConfig(settings); this.incrementConcurrentRequests(this.getHostname(url)); 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(this.getHostname(url), profiler.duration); this.decrementConcurrentRequests(this.getHostname(url)); } } getHostname(url) { return new URL(url).hostname; } getCustomError(method, url, data, error) { var _a, _b; return { method, url, body: data, response: (_a = error.response) === null || _a === void 0 ? void 0 : _a.data, status: (_b = error.response) === null || _b === void 0 ? void 0 : _b.status, message: error.message, name: error.name, stack: error.stack, }; } }; ApiService.concurrentRequests = 0; 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); exports.ApiService = ApiService; //# sourceMappingURL=api.service.js.map