UNPKG

@sap/cli-core

Version:

Command-Line Interface (CLI) Core Module

84 lines (83 loc) 3.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.create = void 0; const config_1 = require("../../../config"); const http_1 = require("../../../utils/http"); const utils_1 = require("./utils"); const utils_2 = require("../authentication/oauth/tokenProvider/utils"); const logger_1 = require("../../../logger"); const constants_1 = require("../../../constants"); const getLogger = () => (0, logger_1.get)("commands.handler.fetch"); const removeCsrfTokenFromConfig = () => { const config = (0, config_1.get)(); delete config[constants_1.X_CSRF_TOKEN]; }; // developer.mozilla.org/en-US/docs/Web/HTTP/Redirections const REDIRECT_STATUS_CODES = [301, 302, 303, 307, 308]; const REDIRECT_WITHOUT_CHANGE = [307, 308]; const fetchData = async (method, path, parameterMappings, responsePostProcessor) => { const config = (0, config_1.get)(); (0, utils_1.checkConfiguration)(config); const conf = await (0, utils_1.buildHttpConfig)(method, path, parameterMappings); const response = await (0, http_1.fetch)(conf); removeCsrfTokenFromConfig(); await (0, utils_1.handleResponse)(response.data, response.headers); if (responsePostProcessor) { await responsePostProcessor(response); } }; const handle401 = async (method, path, parameterMappings) => { const { debug, error } = getLogger(); debug("response status is 401, trying to refresh access_token"); try { await (0, utils_2.refreshToken)(true); await fetchData(method, path, parameterMappings); debug("refreshing token and fetching data succeeded"); } catch (errRefresh) { error("refreshing token and fetching data again failed", errRefresh); throw errRefresh; } }; const handleRedirect = async (error, method, redirect) => { const location = error.response?.headers.location; if (!location) { throw new Error("location header is not present for redirect"); } let newMethod = method; if (!REDIRECT_WITHOUT_CHANGE.includes(error.response?.status)) { newMethod = "GET"; } await redirect(newMethod, location); }; const handleError = async (error, method, redirect, path, parameterMappings) => { const { error: logError } = getLogger(); logError("failed to fetch data", error); if (error.response?.data && (0, config_1.get)().verbose) { await (0, utils_1.handleResponseData)(error.response?.data); } if (error.response?.status === 401) { await handle401(method, path, parameterMappings); } else if (REDIRECT_STATUS_CODES.includes(error.response?.status)) { await handleRedirect(error, method, redirect); } else { throw error; } }; const runRequest = (method, path, parameterMappings, responsePostProcessor) => async () => { try { await fetchData(method, path, parameterMappings, responsePostProcessor); } catch (errFetch) { const redirect = (newMethod, location) => runRequest(newMethod, location, parameterMappings, responsePostProcessor)(); await handleError(errFetch, method, redirect, path, parameterMappings); } }; /* jscpd:ignore-start */ const create = (method, path, parameterMappings, responsePostProcessor) => { /* jscpd:ignore-end */ return async () => runRequest(method, path, parameterMappings, responsePostProcessor); }; exports.create = create;