UNPKG

@apistudio/apim-cli

Version:

CLI for API Management Products

267 lines (266 loc) 13.9 kB
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); } };