@apistudio/apim-cli
Version:
CLI for API Management Products
195 lines • 11.2 kB
JavaScript
/**
* Copyright IBM Corp. 2024, 2025
*/
import JSZip from 'jszip';
import yaml from 'js-yaml';
import { checkFileExtension } from '../utils.js';
import { AppConstants } from '../constants/app.constants.js';
import { Logger } from '@apic/studio-shared';
export class DataPowerAdapter {
async checkForDataPowerAssembly(buffer) {
const zipContent = await this.loadZipFromBuffer(buffer);
let isdataPower = false;
for (const fileName in zipContent.files) {
const entry = zipContent.files[fileName];
if (entry && !entry.dir && checkFileExtension(fileName)) {
const content = await entry.async('string');
isdataPower = await this.hasDataPowerAsset(content);
if (isdataPower) {
return true;
}
}
}
return isdataPower;
}
async getDataPowerAssemblyContent(buffer) {
const zipContent = await this.loadZipFromBuffer(buffer);
const policySeqToSpecRef = new Map();
const corsToSpecRef = new Map();
const propertiesToSpecRef = new Map();
//Collect all API references
for (const fileName in zipContent.files) {
const entry = zipContent.files[fileName];
if (entry && !entry.dir && checkFileExtension(fileName)) {
const content = await entry.async('string');
const yamlContents = yaml.loadAll(content);
for (const yamlContent of yamlContents) {
if (yamlContent.kind?.toLowerCase() === 'api') {
const specStr = JSON.stringify(yamlContent.spec);
const specObj = yaml.load(specStr);
let apiSpecRef;
if (yamlContent.metadata &&
yamlContent.metadata.type &&
yamlContent.metadata.type === 'SOAP') {
apiSpecRef = specObj?.['rest-def']?.$path;
}
else {
apiSpecRef = specObj?.['api-spec'].$path;
}
const policySeqRefItems = specObj?.[AppConstants.POLICY_SEQ];
const policySeqRef = Array.isArray(policySeqRefItems)
? policySeqRefItems.map((e) => e.$ref)[0]
: '';
if (policySeqRef && apiSpecRef) {
policySeqToSpecRef.set(policySeqRef, apiSpecRef); // Create a map for policy seq to apispec file
}
const corsRef = specObj?.cors?.$ref;
if (corsRef && apiSpecRef) {
corsToSpecRef.set(corsRef, apiSpecRef);
}
const propertiesRef = specObj?.properties?.$ref;
if (propertiesRef && apiSpecRef) {
propertiesToSpecRef.set(propertiesRef, apiSpecRef);
}
}
}
}
}
const specToAssemblyContentMap = new Map();
//Process DataPowerAssembly content
if (policySeqToSpecRef.size > 0) {
for (const fileName in zipContent.files) {
const entry = zipContent.files[fileName];
if (entry && !entry.dir && checkFileExtension(fileName)) {
const content = await entry.async('string');
const yamlContents = yaml.loadAll(content);
for (const yamlContent of yamlContents) {
// Find datapower kind file and get the dataPowerAssemblyContent
if (yamlContent.kind?.toLowerCase() === AppConstants.DATAPOWERASSEMBLY) {
const metadata = yamlContent.metadata;
const dataPowerAssemblyContent = yamlContent.spec;
if (metadata.namespace && metadata.name && metadata.version) {
const dataPowerAssemblyRef = metadata.namespace.concat(':', metadata.name, ':', metadata.version);
// From the datapower metadata check if key exists in the policySeqToSpecRef map replace content in the spec file
if (policySeqToSpecRef.has(dataPowerAssemblyRef)) {
const specfile = policySeqToSpecRef.get(dataPowerAssemblyRef);
if (specfile && dataPowerAssemblyContent) {
specToAssemblyContentMap.set(specfile, dataPowerAssemblyContent);
}
}
}
}
}
}
}
}
// Third pass: Process CORS content and add it to the x-ibm-configuration field
if (corsToSpecRef.size > 0) {
for (const fileName in zipContent.files) {
const entry = zipContent.files[fileName];
if (entry && !entry.dir && checkFileExtension(fileName)) {
const content = await entry.async('string');
const yamlContents = yaml.loadAll(content);
for (const yamlContent of yamlContents) {
if (yamlContent.kind?.toLowerCase() === 'cors') {
const metadata = yamlContent.metadata;
const corsContent = yamlContent.spec;
if (metadata.namespace && metadata.name && metadata.version) {
const corsRef = metadata.namespace.concat(':', metadata.name, ':', metadata.version);
// Check if this CORS reference exists in our map
if (corsToSpecRef.has(corsRef)) {
const specfile = corsToSpecRef.get(corsRef);
if (specfile && corsContent) {
// If we already have DataPowerAssembly content for this spec file
if (specToAssemblyContentMap.has(specfile)) {
const existingContent = specToAssemblyContentMap.get(specfile);
// Add CORS content under x-ibm-configuration
if (existingContent && existingContent['x-ibm-configuration']) {
existingContent['x-ibm-configuration'].cors = {};
existingContent['x-ibm-configuration'].cors.enabled = true;
existingContent['x-ibm-configuration'].cors.policy = [
{
'allow-credentials': corsContent.rules[0].allowCredentials,
'allow-origin': corsContent.rules[0].originList,
'expose-headers': {
predefined: corsContent.rules[0].exposeHeaders?.predefined,
backend: corsContent.rules[0].exposeHeaders?.backend,
custom: corsContent.rules[0].exposeHeaders?.custom,
},
},
];
specToAssemblyContentMap.set(specfile, existingContent);
}
}
}
}
}
}
}
}
}
}
// Fourth pass: Process Properties content and add it to the x-ibm-configuration field
if (propertiesToSpecRef.size > 0) {
for (const fileName in zipContent.files) {
const entry = zipContent.files[fileName];
if (entry && !entry.dir && checkFileExtension(fileName)) {
const content = await entry.async('string');
const yamlContents = yaml.loadAll(content);
for (const yamlContent of yamlContents) {
if (yamlContent.kind?.toLowerCase() === 'properties') {
const metadata = yamlContent.metadata;
const propertiesContent = yamlContent.spec;
if (metadata.namespace && metadata.name && metadata.version) {
const propertiesRef = metadata.namespace.concat(':', metadata.name, ':', metadata.version);
// Check if this Properties reference exists in our map
if (propertiesToSpecRef.has(propertiesRef)) {
const specfile = propertiesToSpecRef.get(propertiesRef);
if (specfile && propertiesContent) {
// If we already have DataPowerAssembly content for this spec file
if (specToAssemblyContentMap.has(specfile)) {
const existingContent = specToAssemblyContentMap.get(specfile);
// Add Properties content under x-ibm-configuration
existingContent['x-ibm-configuration'].properties = {};
if (existingContent && existingContent['x-ibm-configuration']) {
existingContent['x-ibm-configuration'].properties = propertiesContent;
specToAssemblyContentMap.set(specfile, existingContent);
}
}
}
}
}
}
}
}
}
}
return specToAssemblyContentMap;
}
async loadZipFromBuffer(fileBuffer) {
Logger.info('Loading ZIP from buffer');
const zip = new JSZip();
return zip.loadAsync(fileBuffer);
}
async hasDataPowerAsset(content) {
const yamlContents = yaml.loadAll(content);
for (const yamlContent of yamlContents) {
const isDataPower = yamlContent.kind && yamlContent.kind.toLowerCase() == AppConstants.DATAPOWERASSEMBLY;
if (isDataPower) {
return isDataPower;
}
}
return false;
}
}
//# sourceMappingURL=datapower-adapter.js.map