UNPKG

@apistudio/apim-cli

Version:

CLI for API Management Products

195 lines 11.2 kB
/** * 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