UNPKG

@apistudio/apim-cli

Version:

CLI for API Management Products

61 lines (60 loc) 3.78 kB
import { checkForNullOrUndefined } from "../common/data-helper.js"; import path from "node:path"; import fs from "node:fs"; import { showError, showInfo, showWarning } from "../common/message-helper.js"; const bundleApiDependency = (asset, searchResult, cachedUnProcessedAsset, rootDirPath, project, zipFile) => { const sourceProjectName = cachedUnProcessedAsset.sourceProject; if (!sourceProjectName) { showError(`Source project not found for API dependency ${cachedUnProcessedAsset.ref}`); return; } // Pass the timestamp as the unique value that gets appended to project name const timeStamp = Date.now(); // Add API with project folder structure const apiRelativePath = addApiDependencyAsset(searchResult, zipFile, project, // target project name sourceProjectName, rootDirPath, timeStamp); showInfo(`API added: ${project}/${apiRelativePath}`); // Also add the API specification resolveAndAddApiSpec(asset, zipFile, apiRelativePath, project, // target project name sourceProjectName, rootDirPath, timeStamp); }; const addApiDependencyAsset = (file, zip, targetProjectName, sourceProjectName, rootDirPath, timeStamp) => { // Calculate relative path from target project root const targetProjectPath = path.join(rootDirPath, targetProjectName); const relativePath = path.relative(targetProjectPath, path.join(file.parentPath, file.name)); // Add to zip with project folder structure nested inside source project // Result: sourceProject/targetProject/api-assets/api.yml const zipPath = path.join(sourceProjectName, `${targetProjectName}_${timeStamp}`, relativePath); zip.addLocalFile(path.join(file.parentPath, file.name), path.dirname(zipPath)); return relativePath; }; const resolveAndAddApiSpec = (asset, zip, apiFileRelativePath, targetProjectName, sourceProjectName, rootDirPath, timeStamp) => { const apiAsset = asset; const spec = checkForNullOrUndefined(apiAsset.spec, `Spec is not defined for the asset with kind 'API' and name '${apiAsset.metadata?.name}'`); const apiSpec = checkForNullOrUndefined(spec["api-spec"], `Attribute 'api-spec' is not defined for kind 'API' and name '${apiAsset.metadata?.name}'`); const apiSpecPath = checkForNullOrUndefined(apiSpec.$path, `API Definition Path is not found for ${asset}`); // Get the directory where the API file is located const apiFileDir = path.dirname(apiFileRelativePath); // Resolve api spec path relative to project folder by default let resolvedSpecPath = apiSpecPath; if (apiSpecPath.startsWith('../') || apiSpecPath.startsWith('./')) { // Resolve relative path from API file's directory // Example: apiFileDir = "api-assets", apiSpecPath = "../specs/petstore.yaml" // Result: "specs/petstore.yaml" const specPathFromProjectRoot = path.join(apiFileDir, apiSpecPath); resolvedSpecPath = path.normalize(specPathFromProjectRoot); } // Build absolute file system path for reading the spec const absoluteSpecPath = path.join(rootDirPath, targetProjectName, resolvedSpecPath); if (!fs.existsSync(absoluteSpecPath)) { showWarning(`API spec not found: ${absoluteSpecPath} for API ${apiAsset.metadata?.namespace}:${apiAsset.metadata?.name}:${apiAsset.metadata.version}`); return; } // Build zip path using the relative spec path from API // apiSpecPath is already relative (e.g., "specs/petstore.yaml") const zipSpecPath = path.join(sourceProjectName, `${targetProjectName}_${timeStamp}`, resolvedSpecPath); zip.addLocalFile(absoluteSpecPath, path.dirname(zipSpecPath)); showInfo(`Spec added: ${zipSpecPath}`); }; export { bundleApiDependency, addApiDependencyAsset, resolveAndAddApiSpec };