@apistudio/apim-cli
Version:
CLI for API Management Products
170 lines (154 loc) • 4.86 kB
text/typescript
/**
* Copyright Super iPaaS Integration LLC, an IBM Company 2024
*/
import { showError, showInfo } from "../../helpers/common/message-helper.js";
import {
checkForRootDirPermission,
checkIfProjectExists,
checkIfRootDirExists,
} from "../../helpers/apim/root-dir-helper.js";
import {
ASSERT_ADDED,
CHECKING_FOR_PROJECT,
CHECKING_ROOT_DIRECTORY,
SPEC_ADDED,
} from "../../constants/message-constants.js";
import {
checkAndLoadDependencies,
searchAsset,
} from "../../helpers/apim/build-helper.js";
import AdmZip from "adm-zip";
import fs from 'fs';
import { KindEnums } from "@apic/api-model/common/StudioEnums.js";
import {
getParentDir,
getSubDirectory,
normalizePath,
readFile,
} from "../../helpers/common/fs-helper.js";
import { COMMA } from "../../constants/app-constants.js";
import {
checkForNullOrUndefined,
isNullOrUndefined,
} from "../../helpers/common/data-helper.js";
import path from "path";
import { cropPrefix } from "../../helpers/common/string-helper.js";
import { readYaml } from "../../helpers/common/yaml-helper.js";
import { getAPIDefPath } from "../../handlers/api-asset-handler.js";
import { BaseAsset } from "../../model/assets-model.js";
import { processProjectBuild } from "@apic/studio-build";
import { DebugManager } from "../../debug/debug-manager.js";
const executeBuildProjectAssets = async (
project: string,
rootDirPath: string,
assets: string
): Promise<Buffer> => {
try {
/* (*) Validate rootDirPath */
if (DebugManager.getInstance().isDebugEnabled()) {
showInfo(CHECKING_ROOT_DIRECTORY);
}
checkIfRootDirExists(rootDirPath);
checkForRootDirPermission(rootDirPath);
/* (*) Validate projectNames */
if (DebugManager.getInstance().isDebugEnabled()) {
showInfo(CHECKING_FOR_PROJECT);
}
checkIfProjectExists(rootDirPath, project);
/* (*) Iterate and build project archive */
const zipFile = new AdmZip();
checkAndAddAssets(assets, project, rootDirPath, zipFile);
/* (*) Check and Load Dependencies */
checkAndLoadDependencies(rootDirPath, project, zipFile, false);
/* (*) Invoke Studio Build API */
const zipBuffer = await processProjectBuild(zipFile.toBuffer());
/* (*)return the zip file */
return zipBuffer;
} catch (error: unknown) {
showError((error as Error).message);
process.exit(1);
}
};
function addAssetDefinition(
asset: string,
projectDirPath: string,
rootDirPath: string,
zipFile: AdmZip
) {
const result = searchAsset(KindEnums.API, asset, projectDirPath) as fs.Dirent;
const zipPath = `${cropPrefix(
result.parentPath,
normalizePath(rootDirPath)
)}`;
const filePath = normalizePath(`${result.parentPath}/${result.name}`);
zipFile.addLocalFile(filePath, zipPath);
showInfo(ASSERT_ADDED + asset);
return result;
}
function addAPIDefinition(
result: fs.Dirent,
asset: string,
rootDirPath: string,
projectDirPath: string,
zipFile: AdmZip
) {
let $path = getAPIDefPath(
readYaml<BaseAsset>(readFile(result.parentPath, result.name))
);
$path = checkForNullOrUndefined(
$path,
`API Definition Path is not found for ${asset}`
);
let normalizedAPIDefinitionPath = '';
if($path.startsWith('./')||$path.startsWith('../')){
const zipPath = `${cropPrefix(
result.parentPath,
normalizePath(rootDirPath)
)}`;
const filePath=`${zipPath}/${result.name}`;
const baseDir = path.dirname(filePath);
const resolvedPath = path.join(baseDir, $path);
normalizedAPIDefinitionPath = path.normalize(`${rootDirPath}${resolvedPath}`);
}
else{
normalizedAPIDefinitionPath=normalizePath(
`${projectDirPath}/${$path}`
);
}
const zipPathForAPIDefinition = `${cropPrefix(
getParentDir(normalizedAPIDefinitionPath),
normalizePath(rootDirPath)
)}`;
zipFile.addLocalFile(normalizedAPIDefinitionPath, zipPathForAPIDefinition);
showInfo(SPEC_ADDED + $path);
}
const checkAndAddAssets = (
assets: string,
project: string,
rootDirPath: string,
zipFile: AdmZip
) => {
/* (*) check if API asset kinds exists in the given project */
const projectDirPath = getSubDirectory(rootDirPath, project);
const inValidAsset = assets
.split(COMMA)
.find((asset) =>
isNullOrUndefined(searchAsset(KindEnums.API, asset, projectDirPath))
);
if (!isNullOrUndefined(inValidAsset)) {
throw new Error(`Invalid asset of kind 'API' and name ${inValidAsset}`);
}
/* (*) add the asset files along with api specification */
assets.split(COMMA).forEach((asset) => {
// adding kind API
const result = addAssetDefinition(
asset,
projectDirPath,
rootDirPath,
zipFile
);
//adding specification
addAPIDefinition(result, asset, rootDirPath,projectDirPath, zipFile);
});
};
export { executeBuildProjectAssets };