@sap/cli-core
Version:
Command-Line Interface (CLI) Core Module
234 lines (233 loc) • 9.48 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildHttpConfig = exports.configRequiresBody = exports.handleResponse = exports.handleResponseData = exports.buildParameters = exports.handleParameterMapping = exports.getValueFromMappping = exports.handleMappingIn = exports.removeLeadingPathSegmentForPasscode = exports.checkConfiguration = void 0;
exports.getOutputFileName = getOutputFileName;
exports.checkResponseDataForInvalidLoginData = checkResponseDataForInvalidLoginData;
exports.handleResponseHeaders = handleResponseHeaders;
const os_1 = require("os");
const url_1 = require("url");
const lodash_1 = __importDefault(require("lodash"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const constants_1 = require("../../../constants");
const logger_1 = require("../../../logger");
const config_1 = require("../../../config");
const utils_1 = require("../utils");
const ResultHandlerFactory_1 = require("../../../result/ResultHandlerFactory");
const CURLY_OPEN_ENCODED = encodeURIComponent("{");
const CURLY_CLOSED_ENCODED = encodeURIComponent("}");
const checkConfiguration = (config) => {
if (!config.authorization) {
throw new Error("no authorization header");
}
if (!config.host) {
throw new Error("no host");
}
if (!config.publicfqdn) {
throw new Error("no publicfqdn");
}
};
exports.checkConfiguration = checkConfiguration;
const removeLeadingPathSegmentForPasscode = (path) => {
const authenticationMethod = (0, utils_1.getAuthenticationMethod)();
if (authenticationMethod === constants_1.AuthenticationMethod.passcode) {
const segments = path.split("/");
if (constants_1.SEGMENTS_TO_REMOVE_FOR_PASSCODE_AUTH.includes(segments[1])) {
segments.splice(1, 1);
return segments.join("/");
}
}
return path;
};
exports.removeLeadingPathSegmentForPasscode = removeLeadingPathSegmentForPasscode;
const getUrl = (path) => {
if (path.startsWith("http")) {
return new url_1.URL(path);
}
const pathInt = (0, exports.removeLeadingPathSegmentForPasscode)(path);
const targetHost = (0, utils_1.getTargetHost)();
return new url_1.URL(`${targetHost}${pathInt}`);
};
const handleMappingIn = (mapping, url, value, headers, bodyWrapper) => {
if (mapping.in === "query") {
url.searchParams.append(mapping.name, value);
}
else if (mapping.in === "header") {
// eslint-disable-next-line no-param-reassign
headers[mapping.name] = value;
}
else if (mapping.in === "path") {
// eslint-disable-next-line no-param-reassign
url.pathname = url.pathname.replace(new RegExp(`${CURLY_OPEN_ENCODED}${mapping.name}${CURLY_CLOSED_ENCODED}`, "g"), encodeURIComponent(value));
}
else {
if (!bodyWrapper.body) {
// eslint-disable-next-line no-param-reassign
bodyWrapper.body = {};
}
lodash_1.default.set(bodyWrapper.body, mapping.name, value);
}
};
exports.handleMappingIn = handleMappingIn;
const getValueFromMappping = (mapping, config) => {
if (mapping.source.type === "value") {
return mapping.source.value;
}
if (
// mapping.source.type === "option"
config.options[mapping.source.name] === undefined &&
mapping.source.dataType === "boolean") {
return false;
}
// mapping.source.type === "option"
return config.options[mapping.source.name];
};
exports.getValueFromMappping = getValueFromMappping;
const handleParameterMapping = (config, url, headers, bodyWrapper) => (mapping) => {
const value = (0, exports.getValueFromMappping)(mapping, config);
if (value === undefined || value === null) {
return;
}
(0, exports.handleMappingIn)(mapping, url, value, headers, bodyWrapper);
};
exports.handleParameterMapping = handleParameterMapping;
const buildParameters = (path, parameterMappings) => {
const config = (0, config_1.get)();
const bodyWrapper = {
body: undefined,
};
let headers = {};
if (config.data?.type === "file") {
// stackoverflow.com/a/59177066
headers = config.data.content.getHeaders();
bodyWrapper.body = config.data.content;
}
else if (config.data?.type === "json") {
headers = { "Content-Type": "application/json" };
bodyWrapper.body = config.data.content;
}
const url = getUrl(path);
parameterMappings?.forEach((0, exports.handleParameterMapping)(config, url, headers, bodyWrapper));
return {
url,
headers,
body: bodyWrapper.body,
};
};
exports.buildParameters = buildParameters;
/**
* If --output is present: Return value of --output if defined, otherwise take value from outputPath.
* If --output is not present, print response to console
* @param outputPath Optional path defined by server
* @returns Path to output file
*/
function getOutputFileName(outputPath = "") {
const config = (0, config_1.get)();
if (typeof config.options[constants_1.OPTION_OUTPUT.longName] === "boolean" &&
config.options[constants_1.OPTION_OUTPUT.longName]) {
return outputPath;
}
return config.options[constants_1.OPTION_OUTPUT.longName];
}
function checkResponseDataForInvalidLoginData(response) {
if (
// jira.tools.sap/browse/DW101-73607
typeof response === "string" &&
response.includes("Please contact your system administrator and ensure you have an active account on this system.")) {
const logger = (0, logger_1.get)("checkResponseDataForInvalidLoginData");
logger.output("WARNING: You are using an access token which is not known to the tenant. Please check your login credentials.");
logger.debug(response);
return true;
}
return false;
}
const handleResponseData = async (data, outputPath) => {
checkResponseDataForInvalidLoginData(data);
const config = (0, config_1.get)();
if (!config.doNotStoreResult) {
ResultHandlerFactory_1.ResultHandlerFactory.get().setResult(data);
}
if (config.doNotProcessResponseData) {
return;
}
const { output } = (0, logger_1.get)("handler.fetch");
const formatted = config.options.pretty
? JSON.stringify(data, null, 2)
: JSON.stringify(data);
const outputFileName = getOutputFileName(outputPath);
if (outputFileName) {
await fs_extra_1.default.writeFile(outputFileName, formatted);
}
else {
output(formatted);
}
};
exports.handleResponseData = handleResponseData;
function handleResponseHeaders(headers) {
const { error, output } = (0, logger_1.get)("handler.fetch.handleResponseHeaders");
if (headers[constants_1.X_DSP_API_DEPRECATED_PROPERTIES]) {
try {
const deprecatedProperties = JSON.parse(headers[constants_1.X_DSP_API_DEPRECATED_PROPERTIES]);
const deprecatedPropertiesStr = deprecatedProperties
.map((dp) => {
let msg = dp.name;
if (dp.deprecatedWithWave) {
msg += `. Deprecated since version ${dp.deprecatedWithWave}`;
}
if (dp.decommissionedAfterWave) {
msg += `. Decommissioned after version ${dp.decommissionedAfterWave}`;
}
if (dp.sapHelpUrl) {
msg += `. See the SAP Help documentation at ${dp.sapHelpUrl} for more information`;
}
if (dp.customMessage) {
msg += `. ${dp.customMessage}`;
}
return msg;
})
.reduce((prev, curr) => `${prev}${os_1.EOL}\t${curr}`, "");
output(`WARNING: the following properties are deprecated:${deprecatedPropertiesStr}`);
}
catch (err) {
error(`failed to parse deprecated properties via header ${constants_1.X_DSP_API_DEPRECATED_PROPERTIES}`, err);
}
}
}
const handleResponse = async (data, headers) => {
if (headers?.[constants_1.X_CSRF_TOKEN]) {
(0, config_1.set)({ [constants_1.X_CSRF_TOKEN]: headers[constants_1.X_CSRF_TOKEN] });
}
else {
if (data) {
await (0, exports.handleResponseData)(data, headers?.[constants_1.X_OUTPUT_FILE_NAME]);
}
if (headers) {
handleResponseHeaders(headers);
}
}
};
exports.handleResponse = handleResponse;
const configRequiresBody = (method) => ["POST", "PUT", "PATCH"].includes(method.toUpperCase());
exports.configRequiresBody = configRequiresBody;
const buildHttpConfig = async (method, path, parameterMappings) => {
const config = (0, config_1.get)();
const { url, body, headers } = (0, exports.buildParameters)(path, parameterMappings);
const httpConfig = {
url: url.toString(),
method,
data: (0, exports.configRequiresBody)(method) ? body : undefined,
headers: {
...config.authorization,
...headers,
...config.headers,
publicfqdn: config.publicfqdn,
},
};
if ((0, utils_1.getAuthenticationMethod)() === constants_1.AuthenticationMethod.oauth) {
delete httpConfig.headers.publicfqdn;
}
return httpConfig;
};
exports.buildHttpConfig = buildHttpConfig;