@apistudio/apim-cli
Version:
CLI for API Management Products
115 lines (114 loc) • 4.78 kB
JavaScript
import path from "path";
import fs from "fs";
import { isValidAsset } from "./asset-helper.js";
import { readMultiYaml } from "../common/yaml-helper.js";
import { readFile, isYamlFile, isDirectory, isDirOrFileExists, getSubDirectory, normalizePath, } from "../common/fs-helper.js";
import { showWarning, showError } from "../common/message-helper.js";
import { DIRECTORY_DOESNT_EXIST, ERROR_IN_SEARCH_OF_ASSET, NO_ENTRIES_FOUND_FOR_KIND, NO_ASSET_METADATA, IS_FOUND_IN, INVALID_DIRECTORY, } from "../../constants/message-constants.js";
import { COMMA } from "../../constants/app-constants.js";
import { equalsIgnoreCase } from "../common/data-helper.js";
const searchAssetByKind = async (kindToSearch, rootDirPath, projectNames) => {
const projectAssetMetadata = {};
try {
const projects = projectNames.split(COMMA);
for (const project of projects) {
const projectDirPath = getSubDirectory(rootDirPath, project);
if (!isDirOrFileExists(projectDirPath) || !isDirectory(projectDirPath)) {
showWarning(`${DIRECTORY_DOESNT_EXIST} ${projectDirPath}`);
continue;
}
const matchingEntries = searchAssetByKindInDirectory(kindToSearch, projectDirPath);
if (matchingEntries.length > 0) {
for (const entry of matchingEntries) {
const filePath = path.join(entry.parentPath, entry.name);
extractKindMetadata(filePath, project, kindToSearch, projectAssetMetadata);
}
}
else {
showWarning(`${NO_ENTRIES_FOUND_FOR_KIND} - '${kindToSearch}' ${IS_FOUND_IN} '${projectDirPath}'`);
}
}
return formatMetadataResult(projectAssetMetadata);
}
catch (error) {
showError(`${ERROR_IN_SEARCH_OF_ASSET} ${kindToSearch}: ${error.message}`);
throw error;
}
};
const searchAssetByKindInDirectory = (kindToSearch, projectDirPath) => {
if (!isDirOrFileExists(projectDirPath) || !isDirectory(projectDirPath)) {
throw new Error(`${INVALID_DIRECTORY} ${projectDirPath}`);
}
try {
const entries = fs.readdirSync(projectDirPath, {
withFileTypes: true,
recursive: true,
});
return entries.filter((entry) => {
if (entry.isDirectory()) {
return false;
}
if (!isYamlFile(entry.name)) {
return false;
}
const assets = readMultiYaml(normalizePath(`${entry.parentPath}/${entry.name}`), readFile(entry.parentPath, entry.name));
return containsMatchingKind(assets, kindToSearch);
});
}
catch (error) {
showError(`${ERROR_IN_SEARCH_OF_ASSET} ${kindToSearch}: ${error.message}`);
throw error;
}
};
const containsMatchingKind = (assets, kindToSearch) => {
for (const asset of assets) {
if (isValidAsset(asset) && equalsIgnoreCase(kindToSearch, asset.kind)) {
return true;
}
}
return false;
};
const extractKindMetadata = (filePath, project, kindToSearch, projectAssetMetadata) => {
try {
const fileContent = readFile(path.dirname(filePath), path.basename(filePath));
const yamlContents = readMultiYaml(filePath, fileContent);
const assetMetadata = [];
yamlContents.forEach((yamlContent) => {
if (isValidAsset(yamlContent)) {
const kind = yamlContent.kind ? yamlContent.kind.toLowerCase() : "";
if (kind === kindToSearch.toLowerCase()) {
const metadata = getMetadata(yamlContent);
assetMetadata.push(metadata);
}
}
});
if (assetMetadata.length > 0) {
if (!projectAssetMetadata[project]) {
projectAssetMetadata[project] = [];
}
projectAssetMetadata[project].push(...assetMetadata);
}
return assetMetadata.length > 0;
}
catch (error) {
showError(`${error instanceof Error ? error.message : "Unknown error"}`);
return false;
}
};
const formatMetadataResult = (projectAssetMetadata) => {
if (Object.keys(projectAssetMetadata).length === 0) {
showError(NO_ASSET_METADATA);
}
const result = {};
for (const [project, metadataArray] of Object.entries(projectAssetMetadata)) {
result[project] = metadataArray.join(COMMA);
}
return result;
};
const getMetadata = (asset) => {
const namespace = asset.metadata?.namespace || "";
const name = asset.metadata?.name || "";
const version = asset.metadata?.version || "";
return `${namespace}:${name}:${version}`;
};
export { searchAssetByKind };