@apistudio/apim-cli
Version:
CLI for API Management Products
168 lines (167 loc) • 6.86 kB
JavaScript
import path from 'path';
import envPaths from 'env-paths';
import { constructKey } from '../../helpers/apim/test-helper.js';
import { showError, showInfo, showWarning } from '../../helpers/common/message-helper.js';
import { COMMA, CONFIG_DIRECTORY_NAME, CONFIG_FILE_NAME } from '../../constants/app-constants.js';
import { ALL_ENDPOINTS_FETCHED_FROM_STORE, APPEND_ENDPOINTS_FAILED, CONFIG, CONFIG_FILE_CREATED, CONFIG_FILE_CREATION_FAILED, DEPLOYMENT_DATA_UPDATED, FAILED_TO_SET_ENDPOINT, NO_DATA_TO_PROCESS, NO_ENDPOINTS_IN_STORE, NO_ENDPOINTS_STORE_CONFIGURED, NO_UPDATES_NEEDED, READ_CURRENT_ENDPOINTS_FAILED, SOME_ENDPOINTS_MISSING_FROM_STORE, UPDATE_ENDPOINTS_FAILED } from '../../constants/message-constants.js';
import { checkFileExists, ensureDirectoryExists, readJsonFromFile, writeJsonToFile } from '../../helpers/common/fs-helper.js';
import { DebugManager } from '../../debug/debug-manager.js';
const logIfDebug = (logFn, message) => {
if (DebugManager.getInstance().isDebugEnabled()) {
logFn(CONFIG + message);
}
};
const createConfig = async () => {
const filePath = getConfigFilePath();
try {
await ensureDirectoryExists(path.dirname(filePath));
if (!await checkFileExists(filePath)) {
await writeJsonToFile(filePath, { deployments: [] }, { spaces: 2 });
logIfDebug(showInfo, CONFIG_FILE_CREATED);
}
}
catch (error) {
logIfDebug(showError, `${CONFIG_FILE_CREATION_FAILED} ${error.message}`);
}
};
const getConfigFilePath = () => {
const paths = envPaths(CONFIG_DIRECTORY_NAME);
return path.join(paths.config, CONFIG_FILE_NAME);
};
const formatGatewayResponse = (response) => {
return response.map(apiResponse => ({
api: constructKey(apiResponse),
endpoints: apiResponse.gatewayEndpoints
}));
};
const getCurrentEndpoints = async () => {
const filePath = getConfigFilePath();
let currentData = { deployments: [] };
try {
if (await checkFileExists(filePath)) {
currentData = await readJsonFromFile(filePath);
}
}
catch (error) {
logIfDebug(showError, `${READ_CURRENT_ENDPOINTS_FAILED} ${error.message}`);
}
return currentData;
};
const updateEndpoints = async (formattedResponse) => {
const filePath = getConfigFilePath();
try {
await ensureDirectoryExists(path.dirname(filePath));
await writeJsonToFile(filePath, formattedResponse, { spaces: 2 });
logIfDebug(showInfo, DEPLOYMENT_DATA_UPDATED);
}
catch (error) {
logIfDebug(showError, `${UPDATE_ENDPOINTS_FAILED} ${error.message}`);
}
};
const compareEndpoints = (endpoints1, endpoints2) => {
const sortedEndpoints1 = [...endpoints1].sort();
const sortedEndpoints2 = [...endpoints2].sort();
if (sortedEndpoints1.length !== sortedEndpoints2.length) {
return false;
}
return sortedEndpoints1.every((endpoint, index) => endpoint === sortedEndpoints2[index]);
};
const overwriteEndpoints = async (formattedResponse) => {
try {
const currentData = await getCurrentEndpoints();
const updatesNeeded = formattedResponse.deployments.some(deployment => {
const existingDeployment = currentData.deployments.find(d => d.api === deployment.api);
return existingDeployment && !compareEndpoints(existingDeployment.endpoints, deployment.endpoints);
});
if (updatesNeeded) {
await updateEndpoints(formattedResponse);
}
else {
logIfDebug(showInfo, NO_UPDATES_NEEDED);
}
}
catch (error) {
logIfDebug(showError, `${UPDATE_ENDPOINTS_FAILED} ${error.message}`);
}
};
const appendEndpoints = async (newDeployments) => {
const filePath = getConfigFilePath();
try {
const currentData = await getCurrentEndpoints();
const deploymentsMap = new Map();
currentData.deployments.forEach(deployment => {
deploymentsMap.set(deployment.api, deployment);
});
newDeployments.forEach(deployment => {
deploymentsMap.set(deployment.api, deployment);
});
currentData.deployments = Array.from(deploymentsMap.values());
await writeJsonToFile(filePath, currentData, { spaces: 2 });
logIfDebug(showInfo, DEPLOYMENT_DATA_UPDATED);
}
catch (error) {
logIfDebug(showError, `${APPEND_ENDPOINTS_FAILED} ${error.message}`);
}
};
const setGatewayEndpoint = async (response) => {
const formattedResponse = { deployments: formatGatewayResponse(response) };
if (formattedResponse.deployments.length === 0) {
logIfDebug(showError, NO_DATA_TO_PROCESS);
return;
}
const filePath = getConfigFilePath();
try {
if (!await checkFileExists(filePath)) {
await createConfig();
}
const currentData = await getCurrentEndpoints();
const existingApis = currentData.deployments.map(deployment => deployment.api);
const newDeployments = formattedResponse.deployments.filter(deployment => !existingApis.includes(deployment.api));
await overwriteEndpoints(formattedResponse);
if (newDeployments.length > 0) {
await appendEndpoints(newDeployments);
}
}
catch (error) {
logIfDebug(showError, `${FAILED_TO_SET_ENDPOINT} ${error.message}`);
}
};
const getGatewayEndpoints = async (apiString) => {
const filePath = getConfigFilePath();
logIfDebug(showInfo, `Searching config file ${filePath} for ${apiString} endpoints`);
if (!await checkFileExists(filePath)) {
logIfDebug(showInfo, NO_ENDPOINTS_STORE_CONFIGURED);
return { foundEndpoints: {}, notFoundApis: '' };
}
const foundEndpoints = {};
const notFoundApis = [];
const apis = apiString.split(',').map(api => api.trim());
const data = await readJsonFromFile(filePath);
let allApisFound = true;
for (const api of apis) {
showWarning(api);
const matchedDeployment = data.deployments.find(deployment => deployment.api === api);
if (matchedDeployment) {
foundEndpoints[api] = matchedDeployment.endpoints;
}
else {
notFoundApis.push(api);
allApisFound = false;
}
}
if (Object.keys(foundEndpoints).length > 0) {
if (allApisFound) {
logIfDebug(showInfo, ALL_ENDPOINTS_FETCHED_FROM_STORE);
}
else {
logIfDebug(showInfo, SOME_ENDPOINTS_MISSING_FROM_STORE);
}
}
else {
logIfDebug(showInfo, NO_ENDPOINTS_IN_STORE);
}
showWarning(JSON.stringify(foundEndpoints));
showWarning(JSON.stringify(notFoundApis));
return { foundEndpoints, notFoundApis: notFoundApis.join(COMMA) };
};
export { getGatewayEndpoints, setGatewayEndpoint };