UNPKG

@zambelz/zhc

Version:
268 lines 10.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = executeRestApi; const node_path_1 = __importDefault(require("node:path")); const node_fs_1 = __importDefault(require("node:fs")); const global_1 = require("../../../utils/global"); const common_1 = require("../../../utils/common"); const config_1 = require("../../../utils/config"); const logger_1 = require("../../../utils/logger"); const scriptExecutor_1 = __importDefault(require("../shared/scriptExecutor")); const requestScript_1 = require("../shared/requestScript"); const getEnvData = (profile, env) => { try { const configData = (0, config_1.getConfigData)(); const targetProfile = profile || configData?.defaultProfile; const envDirPath = node_path_1.default.join(global_1.PROFILES_PATH, targetProfile, "env"); const targetEnv = `${env || "default"}.jsonc`; const envFilePath = node_path_1.default.join(envDirPath, targetEnv); const envContent = node_fs_1.default.readFileSync(envFilePath, "utf-8"); return { path: envFilePath, content: envContent, }; } catch (err) { throw new Error(`Failed to get env data: ${err}`); } }; const getEndpointData = (name, profile) => { if (!name || name.trim() === "") { throw new Error("Name is required"); } try { const configData = (0, config_1.getConfigData)(); const targetProfile = profile || configData?.defaultProfile; const endpointsDirPath = node_path_1.default.join(global_1.PROFILES_PATH, targetProfile, "endpoints"); const targetEndpointPath = name.split(":").slice(0, -1).join("/"); const targetEndpointName = name.split(":").slice(-1)[0]; const endpointFilePath = node_path_1.default.join(endpointsDirPath, `${targetEndpointPath || "default"}.jsonc`); const endpointContent = node_fs_1.default.readFileSync(endpointFilePath, "utf-8"); const content = (0, common_1.parseContent)(endpointContent); const data = Object.entries(content.parsed) .filter(([key]) => key === targetEndpointName)[0]; return { path: endpointFilePath, data: data[1] }; } catch (err) { (0, logger_1.logError)(`${err}`); return undefined; } }; const assignValueFromVar = (src, target) => { let result = { ...target }; const hasBracket = (str) => { return str[0] === "{" && str[1] === "{" && str[str.length - 1] === "}" && str[str.length - 2] === "}"; }; for (const [key, value] of Object.entries(target)) { if (!hasBracket(value)) { continue; } const paramKey = value.slice(2, value.length - 2); if (src[paramKey]) { result[key] = src[paramKey]; } else { result[key] = ""; } } return result; }; const assignValueFromArgs = (target, args) => { let result = { ...target }; if (!args || args.trim() === "") { return result; } const argObjects = args.split(":").map((arg) => { const [key, value] = arg.split("="); return { [key]: value }; }); for (const arg of argObjects) { const key = Object.keys(arg)[0]; const value = Object.values(arg)[0]; if (target[key]) { result[key] = value; } } return result; }; const assignValueFromScript = (target) => { let result = { ...target }; const hasScriptSign = (str) => { return str[0] === "<" && str[1] === "%" && str[str.length - 2] === "%" && str[str.length - 1] === ">"; }; const getScriptName = (key) => { const openParenthesisIndex = key.indexOf("("); return key.slice(2, openParenthesisIndex); }; const getArgs = (key) => { const openParenthesisIndex = key.indexOf("("); const closeParenthesisIndex = key.indexOf(")"); return key.slice(openParenthesisIndex + 1, closeParenthesisIndex) .split(","); }; for (const [key, value] of Object.entries(target)) { if (!hasScriptSign(value)) { continue; } const scriptName = getScriptName(value); const scriptFn = value.slice(2, value.length - 2); const args = getArgs(scriptFn); const valueFromScript = (0, scriptExecutor_1.default)(scriptName, ...args); if (valueFromScript) { result[key] = valueFromScript; } } return result; }; const assignEndpointVariables = (src, endpoint) => { const endpointVariables = endpoint.match(/\{\{(.+?)\}\}/g); if (!endpointVariables) { return endpoint; } let result = endpoint; for (const variable of endpointVariables) { const variableName = variable.slice(2, variable.length - 2); const variableValue = src[variableName]; if (!variableValue) { continue; } const formattedVariable = `${variableValue}`.trim().replace(/\s+/g, " "); const finalVariable = formattedVariable.replaceAll(/\s/g, "%20"); result = result.replace(variable, finalVariable); } return result; }; const configureRequest = (envData, endpointData, additionalArgs) => { if (!envData || !endpointData) { (0, logger_1.logError)("Environment or endpoint data not found"); return { method: "GET", finalURL: "", requestData: {} }; } const endpointPath = assignEndpointVariables(envData, endpointData["path"]); const fullURL = `${envData.protocol}://${envData.baseURL}${endpointPath}`; const method = endpointData["method"]; const headers = assignValueFromScript(assignValueFromArgs(assignValueFromVar(envData, endpointData["headers"]), additionalArgs)); const params = assignValueFromScript(assignValueFromArgs(assignValueFromVar(envData, endpointData["params"]), additionalArgs)); let finalURL = fullURL; let requestData = {}; switch (method) { case "GET": // TODO: Need to revisit this part finalURL = params && Object.keys(params).length > 0 ? `${fullURL}?${new URLSearchParams(params).toString()}` : fullURL; requestData = { method, headers }; break; case "POST": case "PUT": case "PATCH": requestData = { method, headers, body: params ? params : "" }; break; case "DELETE": break; } return { method, finalURL, requestData }; }; const constructResponse = async (method, response) => { let responseHeaders = {}; for (const [key, value] of response.headers.entries()) { responseHeaders[key] = value; } const contentType = responseHeaders["content-type"]; if (contentType.includes("text/html")) { return await response.text(); } const result = {}; if (response.status > 499) { result["status"] = response.status; result["error"] = response.statusText; return result; } const responseBody = await response.json(); result[method] = response.url; result["status"] = response.status; result["headers"] = responseHeaders; result["cookie"] = response.headers.getSetCookie(); result["body"] = responseBody; return result; }; const httpRequest = async (opt) => { const verbose = opt?.verbose; try { const env = getEnvData(opt?.profile, opt?.env); if (!env) { (0, logger_1.logError)("Environment data not found"); return; } const envContent = (0, common_1.parseContent)(env.content); const envData = envContent.parsed; const protocol = envData.protocol; const baseURL = envData.baseURL; if (!protocol || !baseURL) { (0, logger_1.logError)("Base URL not found"); return; } const name = opt?.call; const endpoint = getEndpointData(name, opt?.profile); if (!endpoint) { (0, logger_1.logError)("Endpoint data not found"); return; } const endpointData = endpoint.data; const preRequestScript = endpointData.scripts?.pre; let updatedEnv = envData; if (preRequestScript) { updatedEnv = (0, requestScript_1.execPreRequestScript)(preRequestScript, env, verbose); } const additionalArgs = opt?.args; const { method, finalURL, requestData } = configureRequest(envData, endpointData, additionalArgs); if (verbose) { (0, logger_1.logInfo)("[REST] Request Payload:"); console.log({ destination: finalURL, ...requestData }); console.log(); } const response = await fetch(finalURL, { ...requestData, body: JSON.stringify(requestData.body) }); const httpResponse = await constructResponse(method, response); if (typeof httpResponse === "string") { return httpResponse; } const postRequestScript = endpointData.scripts?.post; if (postRequestScript) { (0, requestScript_1.execPostRequestScript)(postRequestScript, { path: env.path, unparseable: envContent.unparseable, parsed: updatedEnv }, httpResponse, verbose); } return httpResponse; } catch (err) { (0, logger_1.logError)(`${err}`); } }; async function executeRestApi(options) { console.time("[REST] API Request Time"); const response = await httpRequest(options); console.log("[REST] API Response:"); console.dir(response, { depth: 5 }); console.log(); console.timeEnd("[REST] API Request Time"); } //# sourceMappingURL=restApiCall.js.map