@apistudio/apim-cli
Version:
CLI for API Management Products
125 lines (124 loc) • 5.58 kB
JavaScript
import { checkFileExtension, constructErrorResponse, DeployValidationException, isRelativePath, isValidAsset, ZipProcessor, } from '../index.js';
import { BuildProjectAssets } from '../build-project-assets.js';
import yaml from 'js-yaml';
import path from 'path';
import JSZip from 'jszip';
import { LogWrapper } from '../service/log-wrapper.js';
import { AppConstants } from '../constants/app.constants.js';
export const processBuild = async (fileBuffer) => {
LogWrapper.logInfo('0003', 'Starting build process.');
const obj = new ZipProcessor(fileBuffer);
LogWrapper.logInfo('0003', 'Processing zip file.');
const result = await obj.processZip();
if (!result) {
LogWrapper.logError('0003', 'Build process failed.');
throw new Error(JSON.stringify(constructErrorResponse()));
}
LogWrapper.logInfo('0003', 'Build process succeeded.');
const { buildZip: gatewayZip } = result;
LogWrapper.logInfo('0003', 'Generating zip buffer from gatewayZip.');
const zipBuffer = await gatewayZip.generateAsync({ type: 'nodebuffer' });
LogWrapper.logInfo('0003', 'Zip buffer generation successful.');
return { zipBuffer };
};
export const processGatewayJson = async (fileBuffer) => {
LogWrapper.logInfo('0003', 'Starting extraction of gateway JSON.');
const obj = new ZipProcessor(fileBuffer);
return obj.extractGatewaysJson(fileBuffer);
};
export const normalizeZipPaths = async (zip) => {
LogWrapper.logDebug('0003', 'Starting path normalization in zip file.');
const normalizedZip = new JSZip();
await Promise.all(Object.values(zip.files).map(async (file) => {
const normalizedPath = path.normalize(file.name);
if (file.dir) {
normalizedZip.folder(normalizedPath);
LogWrapper.logDebug('0301', 'directory', `${normalizedPath}`);
}
else {
const fileData = await file.async('nodebuffer');
normalizedZip.file(normalizedPath, fileData);
LogWrapper.logDebug('0301', 'file', `${normalizedPath}`);
}
}));
LogWrapper.logDebug('0003', 'Path normalization completed.');
return normalizedZip;
};
export const updateRelativePath = async (asset, basePath) => {
const extract = (obj) => {
for (const key in obj) {
const value = obj[key];
if (key === AppConstants.pathVariable && typeof value === 'string') {
if (isRelativePath(value)) {
const baseDir = path.dirname(basePath);
const resolvedPath = path.join(baseDir, value);
const normalizedPath = path.normalize(resolvedPath).replace(/\\+/g, '/');
obj[key] = normalizedPath.slice(normalizedPath.indexOf('/') + 1);
}
}
else if (typeof value === 'object' && value !== null) {
extract(value);
}
}
};
if (asset.spec) {
extract(asset.spec);
}
return asset;
};
export const updatePathValueInContent = async (content, basePath) => {
const parsedObjs = yaml.loadAll(content);
const updatedObjs = await Promise.all(parsedObjs.map(async (obj) => {
if (isValidAsset(obj)) {
return await updateRelativePath(obj, basePath);
}
return obj;
}));
return updatedObjs.map(obj => yaml.dump(obj)).join('---\n');
};
export const resolveRelativePaths = async (zipBuffer) => {
LogWrapper.logDebug('0003', 'Starting path normalization in zip file.');
const zip = await JSZip.loadAsync(zipBuffer);
const resolvedZip = new JSZip();
await Promise.all(Object.values(zip.files).map(async (file) => {
if (file.dir) {
resolvedZip.folder(file.name);
LogWrapper.logDebug('0301', 'directory', file.name);
}
else {
const nameArray = file.name.split(path.sep);
const name = nameArray[nameArray.length - 1];
if (checkFileExtension(name)) {
const content = await file.async('string');
const updatedContent = await updatePathValueInContent(content, file.name);
resolvedZip.file(file.name, updatedContent);
}
else {
const fileData = await file.async('nodebuffer');
resolvedZip.file(file.name, fileData);
}
}
}));
LogWrapper.logDebug('0003', 'Path normalization completed.');
return resolvedZip;
};
export const processProjectBuild = async (fileBuffer) => {
LogWrapper.logInfo('0003', 'Starting project build processing.');
const zip = await JSZip.loadAsync(fileBuffer);
LogWrapper.logDebug('0003', 'Loading and normalizing zip paths.');
const normalizedZip = await normalizeZipPaths(zip);
const normalizedBuffer = await normalizedZip.generateAsync({ type: 'nodebuffer' });
const resolvedZip = await resolveRelativePaths(normalizedBuffer);
LogWrapper.logDebug('0003', 'Normalized zip buffer generated.');
const obj = new BuildProjectAssets();
LogWrapper.logInfo('0003', 'Processing normalized project zip.');
const result = await obj.processProjectZip(await resolvedZip.generateAsync({
type: 'nodebuffer',
}));
if (!result) {
LogWrapper.logError('0003', 'Project build processing failed.');
throw new DeployValidationException('Asset Validation Failed For Deloyment');
}
LogWrapper.logInfo('0003', 'Project build processing succeeded.');
return result.generateAsync({ type: 'nodebuffer' });
};