@apistudio/apim-cli
Version:
CLI for API Management Products
267 lines (266 loc) • 13.9 kB
JavaScript
import { executeDeployment, prepareGatewayJson } from '../../deployers/project/projects-deployer.js';
import { showError, showWarning, showInfo } from '../../helpers/common/message-helper.js';
import { buildAssets } from './build-action-helper.js';
import { processEndpointFromResponse, addEndpointToZip, testAssets, testProjects, combineTestAsset, createJSONBuffer, findProjectForApi, buildAndDeployAssets, updateEndpointZip, formattedEndpoints, } from '../../helpers/apim/test-helper.js';
import { MULTIPLE_PROJECTS_NOT_ALLOWED, IGNORE_PROJECT_ARG, IGNORE_NAMES_OPT, ENDPOINT_TEST_SUCCESS, CREATED_TEST_ZIP, API_DETAILS_MISSING, RETRY_TEST_COMMAND, DEPLOYMENT_DETAILS_NOT_IDENTIFIED_LOCALLY, DEPLOYMENT_DOESNOT_OVERWRITE, ERROR_PROCESSING_ENDPOINT, ENDPOINT_ARGUMENT_NOT_AVAILABLE, NO_VALID_ENDPOINT_FOUND, MISMATCH_IN_API_AND_ENDPOINT, CREATED_BUILD_ZIP } from '../../constants/message-constants.js';
import { BUILD, COMMA, TEST } from '../../constants/app-constants.js';
import { getGatewayEndpoints } from '../../configure/endpoints/config.js';
import { createBuildZip } from '../../helpers/common/fs-helper.js';
import { getOutputPath } from './../helpers/build-action-helper.js';
import validateEndpoint from '../../validators/endpoint-validator.js';
export const getGatewayJson = async (options, gatewayPassword) => {
const overwriteFlag = options.deploy;
let is_mcsp_enabled = false;
if (options.authToken) {
is_mcsp_enabled = true;
}
return prepareGatewayJson(options.target, options.username, gatewayPassword, overwriteFlag, is_mcsp_enabled);
};
export const handleTestWarnings = (projects, options) => {
if (projects && options.all) {
showWarning(IGNORE_PROJECT_ARG);
}
if (options.names && options.all) {
showWarning(IGNORE_NAMES_OPT);
}
};
const handleMultipleProjectsError = (projects) => {
const projectList = projects.split(COMMA);
if (projectList.length > 1) {
showError(MULTIPLE_PROJECTS_NOT_ALLOWED);
return true;
}
return false;
};
const displayGatewayError = () => {
showError(API_DETAILS_MISSING);
showError(RETRY_TEST_COMMAND);
};
const displayDeploymentWarning = () => {
showWarning(DEPLOYMENT_DETAILS_NOT_IDENTIFIED_LOCALLY);
showWarning(DEPLOYMENT_DOESNOT_OVERWRITE);
};
const handleNotFoundApisForProjects = async (notFoundApis, apiReference, localDir, gatewayJson, finalZipBuffer) => {
const notFoundApisList = notFoundApis.split(',').map(api => api.trim());
const projectApisMap = findProjectForApi(apiReference, notFoundApisList);
const { buildBuffer, deploymentResult } = await buildAndDeployAssets(localDir, projectApisMap, gatewayJson);
const newEndpointFile = processEndpointFromResponse(deploymentResult);
const testBuffer = await updateEndpointZip(finalZipBuffer, newEndpointFile);
return { testZipBuffer: testBuffer, buildZipBuffer: buildBuffer };
};
const handleNotFoundApisForAssets = async (notFoundApis, localDir, projects, gatewayJson, finalZipBuffer) => {
const zipBufferToBuild = await buildAssets(notFoundApis, localDir, projects);
const deployResponses = await executeDeployment(gatewayJson, zipBufferToBuild);
const newEndpointFile = processEndpointFromResponse(deployResponses);
const testBuffer = await updateEndpointZip(finalZipBuffer, newEndpointFile);
return { testZipBuffer: testBuffer, buildZipBuffer: zipBufferToBuild };
};
const deployAndAddEndpointForProjects = async (gatewayJson, localDir, finalZipBuffer, ApiReference) => {
const { buildBuffer, deploymentResult } = await buildAndDeployAssets(localDir, ApiReference, gatewayJson);
const endpointFile = processEndpointFromResponse(deploymentResult);
const testBuffer = addEndpointToZip(finalZipBuffer, endpointFile);
return { testZipBuffer: testBuffer, buildZipBuffer: buildBuffer };
};
const deployAndAddEndpointForAssets = async (gatewayJson, localDir, apiReference, projects, testZipBuffer) => {
const zipBufferToBuild = await buildAssets(apiReference, localDir, projects);
const deployResponses = await executeDeployment(gatewayJson, zipBufferToBuild);
const endpointFile = processEndpointFromResponse(deployResponses);
const testBuffer = addEndpointToZip(testZipBuffer, endpointFile);
return { testZipBuffer: testBuffer, buildZipBuffer: zipBufferToBuild };
};
const handleFoundEndpoints = async (foundEndpoints, finalZipBuffer) => {
const endpointFile = createJSONBuffer(foundEndpoints);
const testBuffer = addEndpointToZip(finalZipBuffer, endpointFile);
return { testZipBuffer: testBuffer, buildZipBuffer: undefined };
};
const hasGatewayDetails = (options) => {
return Boolean(options.target && options.username && options.password);
};
export const handleDeploymentForProjects = async (options, gatewayJson, localDir, finalZipBuffer, ApiReference) => {
if (!hasGatewayDetails(options)) {
displayGatewayError();
return { testZipBuffer: undefined, buildZipBuffer: undefined };
}
return deployAndAddEndpointForProjects(gatewayJson, localDir, finalZipBuffer, ApiReference);
};
export const handleDeploymentWarning = (options) => {
displayDeploymentWarning();
if (!hasGatewayDetails(options)) {
displayGatewayError();
return { testZipBuffer: undefined, buildZipBuffer: undefined };
}
return null;
};
const handleMissingEndpoints = async (options, gatewayJson, localDir, outputBuffers, apiReference, projects) => {
const warningResult = handleDeploymentWarning(options);
if (warningResult) {
return warningResult;
}
if (outputBuffers.testZipBuffer) {
if (projects) {
outputBuffers = await deployAndAddEndpointForAssets(gatewayJson, localDir, apiReference, projects, outputBuffers.testZipBuffer);
}
else {
outputBuffers = await deployAndAddEndpointForProjects(gatewayJson, localDir, outputBuffers.testZipBuffer, apiReference);
}
}
return outputBuffers;
};
async function processNotFoundApisForProjects(notFoundApis, apiReferencesString, gatewayJson, localDir, testZipBuffer, apiReference) {
return (notFoundApis === apiReferencesString)
? deployAndAddEndpointForProjects(gatewayJson, localDir, testZipBuffer, apiReference)
: handleNotFoundApisForProjects(notFoundApis, apiReference, localDir, gatewayJson, testZipBuffer);
}
export const handleNonDeploymentForProjects = async (apiReferencesString, options, gatewayJson, localDir, finalZipBuffer, apiReference) => {
const result = await getGatewayEndpoints(apiReferencesString);
let outputBuffers = { testZipBuffer: finalZipBuffer, buildZipBuffer: undefined };
if (result) {
const { foundEndpoints, notFoundApis } = result;
if (Object.keys(foundEndpoints).length > 0 && outputBuffers.testZipBuffer) {
formattedEndpoints(foundEndpoints);
outputBuffers = await handleFoundEndpoints(foundEndpoints, outputBuffers.testZipBuffer);
}
if (notFoundApis.length > 0) {
const warningResult = handleDeploymentWarning(options);
if (warningResult) {
return warningResult;
}
if (outputBuffers.testZipBuffer) {
outputBuffers = await processNotFoundApisForProjects(notFoundApis, apiReferencesString, gatewayJson, localDir, outputBuffers.testZipBuffer, apiReference);
}
}
}
else {
outputBuffers = await handleMissingEndpoints(options, gatewayJson, localDir, outputBuffers, apiReference);
}
return outputBuffers;
};
async function processNotFoundApisForAssets(notFoundApis, apiReference, gatewayJson, localDir, projects, testZipBuffer) {
return (notFoundApis === apiReference)
? deployAndAddEndpointForAssets(gatewayJson, localDir, apiReference, projects, testZipBuffer)
: handleNotFoundApisForAssets(notFoundApis, localDir, projects, gatewayJson, testZipBuffer);
}
export const handleNonDeploymentForAssets = async (apiReference, options, gatewayJson, localDir, projects, testZipBuffer) => {
const result = await getGatewayEndpoints(apiReference);
let outputBuffers = { testZipBuffer, buildZipBuffer: undefined };
if (result) {
const { foundEndpoints, notFoundApis } = result;
if (Object.keys(foundEndpoints).length > 0 && outputBuffers.testZipBuffer) {
formattedEndpoints(foundEndpoints);
outputBuffers = await handleFoundEndpoints(foundEndpoints, testZipBuffer);
}
if (notFoundApis.length > 0) {
const warningResult = handleDeploymentWarning(options);
if (warningResult) {
return warningResult;
}
if (outputBuffers.testZipBuffer) {
outputBuffers = await processNotFoundApisForAssets(notFoundApis, apiReference, gatewayJson, localDir, projects, outputBuffers.testZipBuffer);
}
}
}
else {
outputBuffers = await handleMissingEndpoints(options, gatewayJson, localDir, outputBuffers, apiReference, projects);
}
return outputBuffers;
};
export const handleDeploymentForAssets = async (options, gatewayJson, localDir, apiReference, projects, testZipBuffer) => {
if (!hasGatewayDetails(options)) {
displayGatewayError();
return { testZipBuffer: undefined, buildZipBuffer: undefined };
}
return deployAndAddEndpointForAssets(gatewayJson, localDir, apiReference, projects, testZipBuffer);
};
export const handleTestAssets = async (options, projects, localDir, gatewayJson) => {
if (handleMultipleProjectsError(projects)) {
return { testZipBuffer: undefined, buildZipBuffer: undefined };
}
const { zipBuffer, apiReference } = await testAssets(localDir, projects, options.names);
const testZipBuffer = zipBuffer;
if (options.deploy) {
return handleDeploymentForAssets(options, gatewayJson, localDir, apiReference, projects, testZipBuffer);
}
else {
return handleNonDeploymentForAssets(apiReference, options, gatewayJson, localDir, projects, testZipBuffer);
}
};
export const handleTestProjects = async (options, projects, localDir, gatewayJson) => {
const testProject = await testProjects(options.all, localDir, projects);
const { zipBuffer: testZipBuffer, apiReference } = await combineTestAsset(localDir, testProject);
const apiReferencesString = Object.values(apiReference).join(',');
const finalZipBuffer = testZipBuffer;
if (options.deploy) {
const { testZipBuffer: finalTestZipBuffer, buildZipBuffer: finalBuildZipBuffer } = await handleDeploymentForProjects(options, gatewayJson, localDir, finalZipBuffer, apiReference);
return { testZipBuffer: finalTestZipBuffer, buildZipBuffer: finalBuildZipBuffer };
}
else {
const { testZipBuffer: finalTestZipBuffer, buildZipBuffer: finalBuildZipBuffer } = await handleNonDeploymentForProjects(apiReferencesString, options, gatewayJson, localDir, finalZipBuffer, apiReference);
return { testZipBuffer: finalTestZipBuffer, buildZipBuffer: finalBuildZipBuffer };
}
};
const mapEndpoints = (apiReference, endpoints) => {
const apiReferences = apiReference.split(COMMA).map(ref => ref.trim());
const mapped = {};
// 1-1 mapping
if (apiReferences.length === endpoints.length) {
apiReferences.forEach((reference, index) => {
mapped[reference] = [endpoints[index]];
});
}
// n:1 mapping
else if (endpoints.length === 1) {
apiReferences.forEach(reference => {
mapped[reference] = [endpoints[0]];
});
}
// case n:m mapping - throw an error for mismatch
else {
throw new Error(MISMATCH_IN_API_AND_ENDPOINT);
}
return mapped;
};
export const validateEndpointOptions = (options) => {
if (options.endpoints && !options.names) {
showError(ENDPOINT_ARGUMENT_NOT_AVAILABLE);
return false;
}
return true;
};
export const testAssetsForEndpoint = async (options, project, localDir) => {
if (handleMultipleProjectsError(project)) {
return { testZipBuffer: undefined, buildZipBuffer: undefined };
}
const { zipBuffer, apiReference } = await testAssets(localDir, project, options.names);
const testZipBuffer = zipBuffer;
try {
const processedEndpoints = await validateEndpoint(options.endpoints);
if (processedEndpoints === false) {
throw new Error(NO_VALID_ENDPOINT_FOUND);
}
const mappedEndpoints = mapEndpoints(apiReference, processedEndpoints);
if (Object.keys(mappedEndpoints).length === 0) {
return { testZipBuffer: undefined, buildZipBuffer: undefined };
}
const endpointBuffer = createJSONBuffer(mappedEndpoints);
if (!endpointBuffer || endpointBuffer.length === 0) {
return { testZipBuffer: undefined, buildZipBuffer: undefined };
}
const testBuffer = addEndpointToZip(testZipBuffer, endpointBuffer);
return { testZipBuffer: testBuffer, buildZipBuffer: undefined };
}
catch (error) {
showError(` ${ERROR_PROCESSING_ENDPOINT} ${error.message}`);
return { testZipBuffer: undefined, buildZipBuffer: undefined };
}
};
export const writeArchive = async (projects, all, names, testZipBuffer, buildZipBuffer) => {
showInfo(ENDPOINT_TEST_SUCCESS);
const buildZipFileName = await getOutputPath(projects, all, names, BUILD);
const testZipFileName = await getOutputPath(projects, all, names, TEST);
createBuildZip(testZipBuffer, testZipFileName);
showInfo(CREATED_TEST_ZIP + testZipFileName);
if (buildZipBuffer) {
createBuildZip(buildZipBuffer, buildZipFileName);
showInfo(CREATED_BUILD_ZIP + buildZipFileName);
}
};