UNPKG

steadybit

Version:

Command-line interface to interact with the Steadybit API

152 lines 6 kB
"use strict"; // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: 2022 Steadybit GmbH var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.options = void 0; exports.enableRequestLogging = enableRequestLogging; exports.executeApiCall = executeApiCall; const node_fetch_1 = __importDefault(require("node-fetch")); const common_1 = require("./common"); /* * This is required because we are supporting Node.js v14 */ const requirePlatformAccess_1 = require("../config/requirePlatformAccess"); const http_1 = __importDefault(require("http")); const https_1 = __importDefault(require("https")); const TOO_MANY_REQUESTS = 429; exports.options = { maxRetries: 2, defaultWaitTime: 1000, }; const httpAgentOptions = { keepAlive: true, keepAliveMsecs: 60000, timeout: 60000, maxSockets: 64, }; const httpAgent = new http_1.default.Agent(httpAgentOptions); const httpsAgent = new https_1.default.Agent(httpAgentOptions); function enableRequestLogging() { process.env.REQUEST_LOGGING_ENABLED = 'true'; } function doFetch(url, method, headers, body, controller, redirect) { return __awaiter(this, void 0, void 0, function* () { if (process.env.REQUEST_LOGGING_ENABLED === 'true') { console.log(`> HTTP ${method} ${url}`); for (const [key, value] of Object.entries(headers)) { console.log(`> ${key}: ${value}`); } console.log(`> `); if (body) { console.log(body); } console.log(''); } const response = yield (0, node_fetch_1.default)(url, { method, headers, body, signal: controller.signal, agent: getHttpAgent, redirect, }); if (process.env.REQUEST_LOGGING_ENABLED === 'true') { console.log(`< HTTP ${response.status} ${response.statusText}`); for (const [key, value] of response.headers) { console.log(`< ${key}: ${value}`); } console.log(`< `); try { const text = yield response.clone().text(); if (text) { console.log(text); } } catch (_a) { // ignore } console.log(''); } return response; }); } function executeApiCall(_a) { return __awaiter(this, arguments, void 0, function* ({ method, path, queryParameters, body, timeout = 30000, expect2xx = true, redirect = 'error', fullyQualifiedUrl = false, }) { yield (0, requirePlatformAccess_1.ensurePlatformAccessConfigurationIsAvailable)(); const url = fullyQualifiedUrl ? path : yield (0, common_1.toUrl)(path, queryParameters); const headers = yield (0, common_1.getHeaders)(); const controller = new AbortController(); const response = yield doWithRetry(() => __awaiter(this, void 0, void 0, function* () { var _a; const timeoutHandle = setTimeout(() => controller.abort(), timeout); try { return yield doFetch(url, method, headers, body ? JSON.stringify(body) : undefined, controller, redirect); } catch (e) { throw new Error(`Failed to call Steadybit API at ${method} ${url}: ${(_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : 'Unknown Cause'}`, // @ts-expect-error TypeScript doesn't know about error causes yet { cause: e }); } finally { clearTimeout(timeoutHandle); } })); if (expect2xx && !response.ok) { let body = ''; try { body = yield response.text(); } catch (_b) { // ignore } const error = new Error(`Steadybit API at ${method} ${url} responded with unexpected status code: ${response.status} - ${body !== null && body !== void 0 ? body : '<no body>'}`); error.response = response; throw error; } return response; }); } function doWithRetry(fn) { return __awaiter(this, void 0, void 0, function* () { let response; let retry = 0; do { response = yield fn(); if (response.status !== TOO_MANY_REQUESTS) { break; } const resetHeader = response.headers.get('RateLimit-Reset') || response.headers.get('Retry-After'); const retryInSeconds = (resetHeader && Number.parseInt(resetHeader) * 1000) || exports.options.defaultWaitTime; yield sleep(retryInSeconds); } while (retry++ <= exports.options.maxRetries); return response; }); } function sleep(millis) { return new Promise(resolve => { setTimeout(() => { resolve(); }, millis); }); } function getHttpAgent(parsedUrl) { if (parsedUrl.protocol == 'http:') { return httpAgent; } else { return httpsAgent; } } //# sourceMappingURL=http.js.map