UNPKG

@apistudio/apim-cli

Version:

CLI for API Management Products

457 lines (387 loc) 16 kB
import { TestOptionsModel } from '../../model/studio/command-options/test-options-model.js'; 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, APIEndpoints, } 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 { GatewaysJson } from '@apic/studio-shared'; 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' import { TestOutputBuffers } from '../../model/studio/test-response-model.js'; export const getGatewayJson = async (options: TestOptionsModel, gatewayPassword: string): Promise<GatewaysJson> => { 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: string, options: TestOptionsModel) => { if (projects && options.all) { showWarning(IGNORE_PROJECT_ARG); } if (options.names && options.all) { showWarning(IGNORE_NAMES_OPT); } }; const handleMultipleProjectsError = (projects: string): boolean => { 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: string, apiReference: Record<string, string>, localDir: string, gatewayJson: GatewaysJson, finalZipBuffer: Buffer ): Promise<TestOutputBuffers>=> { 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: string, localDir: string, projects: string, gatewayJson: GatewaysJson, finalZipBuffer: Buffer ): Promise<TestOutputBuffers>=> { 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: GatewaysJson, localDir: string, finalZipBuffer: Buffer, ApiReference: Record<string, string> ): Promise<TestOutputBuffers>=> { 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: GatewaysJson, localDir: string, apiReference: string, projects: string, testZipBuffer: Buffer ): Promise<TestOutputBuffers>=> { 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: Record<string, any>, finalZipBuffer: Buffer ): Promise<TestOutputBuffers> => { const endpointFile = createJSONBuffer(foundEndpoints); const testBuffer = addEndpointToZip(finalZipBuffer, endpointFile); return { testZipBuffer: testBuffer, buildZipBuffer: undefined}; }; const hasGatewayDetails = (options: TestOptionsModel): boolean => { return Boolean(options.target && options.username && options.password); }; export const handleDeploymentForProjects = async ( options: TestOptionsModel, gatewayJson: GatewaysJson, localDir: string, finalZipBuffer: Buffer, ApiReference: Record<string, string>, ): Promise<TestOutputBuffers> => { if (!hasGatewayDetails(options)) { displayGatewayError(); return { testZipBuffer: undefined, buildZipBuffer: undefined }; } return deployAndAddEndpointForProjects(gatewayJson, localDir,finalZipBuffer,ApiReference); }; export const handleDeploymentWarning = (options: TestOptionsModel): TestOutputBuffers | null => { displayDeploymentWarning(); if (!hasGatewayDetails(options)) { displayGatewayError(); return { testZipBuffer: undefined, buildZipBuffer: undefined }; } return null; }; const handleMissingEndpoints = async ( options: TestOptionsModel, gatewayJson: GatewaysJson, localDir: string, outputBuffers: TestOutputBuffers, apiReference: any, projects?: string ): Promise<TestOutputBuffers> => { 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: string, apiReferencesString: string, gatewayJson: GatewaysJson, localDir: string, testZipBuffer: Buffer, apiReference: any ): Promise<TestOutputBuffers> { return (notFoundApis === apiReferencesString) ? deployAndAddEndpointForProjects(gatewayJson, localDir, testZipBuffer, apiReference) : handleNotFoundApisForProjects(notFoundApis, apiReference, localDir, gatewayJson, testZipBuffer); } export const handleNonDeploymentForProjects = async ( apiReferencesString: string, options: TestOptionsModel, gatewayJson: GatewaysJson, localDir: string, finalZipBuffer: Buffer, apiReference: any, ): Promise<TestOutputBuffers> => { const result = await getGatewayEndpoints(apiReferencesString); let outputBuffers: TestOutputBuffers = { 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: string, apiReference: string, gatewayJson: GatewaysJson, localDir: string, projects: string, testZipBuffer: Buffer ): Promise<TestOutputBuffers> { return (notFoundApis === apiReference) ? deployAndAddEndpointForAssets(gatewayJson, localDir, apiReference, projects, testZipBuffer) : handleNotFoundApisForAssets(notFoundApis, localDir, projects, gatewayJson, testZipBuffer); } export const handleNonDeploymentForAssets = async ( apiReference: string, options: TestOptionsModel, gatewayJson: GatewaysJson, localDir: string, projects: string, testZipBuffer: Buffer ): Promise<TestOutputBuffers> => { const result = await getGatewayEndpoints(apiReference); let outputBuffers: TestOutputBuffers = { 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: TestOptionsModel, gatewayJson: GatewaysJson, localDir: string, apiReference: any, projects: string, testZipBuffer: Buffer ): Promise<TestOutputBuffers> => { if (!hasGatewayDetails(options)) { displayGatewayError(); return { testZipBuffer: undefined, buildZipBuffer: undefined }; } return deployAndAddEndpointForAssets(gatewayJson, localDir, apiReference, projects, testZipBuffer); }; export const handleTestAssets = async (options: TestOptionsModel, projects: string, localDir: string, gatewayJson: GatewaysJson): Promise<TestOutputBuffers>=> { 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: TestOptionsModel, projects: string, localDir: string, gatewayJson: GatewaysJson ): Promise<TestOutputBuffers> => { 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: string, endpoints: string[]): APIEndpoints => { const apiReferences = apiReference.split(COMMA).map(ref => ref.trim()); const mapped: APIEndpoints = {}; // 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: TestOptionsModel) => { if (options.endpoints && !options.names) { showError(ENDPOINT_ARGUMENT_NOT_AVAILABLE); return false; } return true; }; export const testAssetsForEndpoint = async ( options: TestOptionsModel,project: string,localDir: string): Promise<TestOutputBuffers> => { 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 as Error).message}`); return { testZipBuffer: undefined, buildZipBuffer: undefined }; } }; export const writeArchive = async (projects: string, all: boolean, names: string, testZipBuffer: Buffer, buildZipBuffer: Buffer| undefined) => { 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); } };