@apistudio/apim-cli
Version:
CLI for API Management Products
129 lines (107 loc) • 5.37 kB
text/typescript
import { CoreTransformOrchestrator, IConfigRegistry, ITransformerRegistry, WrappedAsset, ITransformer, IConfigLoader, ConfigLoader, StudioAsset, ApiWithAssets, Metadata, MultiYamlFile } from "@apic/smith-transformer";
import { WMGWRuntimeInventory } from "@apic/wmgw-smith-inventory";
import { getParentDir } from "./path.util.js";
import yaml from 'js-yaml';
/**
* WMGW implementation of the Transform Orchestrator
* Specifically for transforming to WMGW gateway
*/
export class WmgwTransformerOrchestrator extends CoreTransformOrchestrator {
/**
* Create a new WMGW transform orchestrator
* @param configRegistry Configuration registry
* @param transformerRegistry Transformer registry
*/
constructor(
configRegistry: IConfigRegistry,
transformerRegistry: ITransformerRegistry,
configLoader: IConfigLoader
) {
super(configRegistry, transformerRegistry, configLoader, '12.0.0');
this.inventory = new WMGWRuntimeInventory();
}
/**
* Post-transformation hook that organizes assets into execute, catch, and finally sections
* @param transformedAssets Array of transformed assets
* @param resources Resources extracted from the ZIP file
* @param apiName Name of the API being processed
* @param apiMetadata Metadata of the API
* @returns Organized assets in assembly structure
*/
protected processOriginalYamlFile(multiYamlFile: MultiYamlFile, transformedAssetsByApi: Record<string, { metadata: Metadata; output: any[]; }>, assetsByApi: Record<string, ApiWithAssets>): string {
const validApiNames = Object.keys(transformedAssetsByApi);
let validAssets: StudioAsset[] = this.filterAssets(multiYamlFile.assets.filter(asset => asset.kind.toLowerCase() !== 'freeflowpolicysequence'));
const allApiNames = Object.keys(assetsByApi);
const invalidApiNames = allApiNames.filter(apiName => (!validApiNames.includes(apiName)));
for (const apiName of invalidApiNames) {
if (assetsByApi[apiName]) {
const apiAsset = assetsByApi[apiName].api;
const relatedAssets = assetsByApi[apiName].relatedAssets;
const apiAssetKey = `${apiAsset.kind}:${apiAsset.metadata.namespace || 'default'}:${apiAsset.metadata.name}:${apiAsset.metadata.version || '1.0'}`;
const relatedAssetKeys = new Set(relatedAssets.map(asset => {
return `${asset.kind}:${asset.metadata.namespace || 'default'}:${asset.metadata.name}:${asset.metadata.version || '1.0'}`;
}));
validAssets = validAssets.filter(asset => {
const assetKey = `${asset.kind}:${asset.metadata.namespace || 'default'}:${asset.metadata.name}:${asset.metadata.version || '1.0'}`;
return assetKey !== apiAssetKey && !relatedAssetKeys.has(assetKey);
});
}
}
for (const apiName of validApiNames) {
if (assetsByApi[apiName]) {
validAssets.push(assetsByApi[apiName].api);
validAssets.push(...assetsByApi[apiName].relatedAssets);
}
}
const uniqueAssetsMap = new Map<string, StudioAsset>();
for (const asset of validAssets) {
const key = `${asset.kind}:${asset.metadata.namespace || 'default'}:${asset.metadata.name}:${asset.metadata.version || '1.0'}`;
uniqueAssetsMap.set(key, asset);
}
const assetsInThisFile = Array.from(uniqueAssetsMap.values()).filter(asset => {
return multiYamlFile.assets.some(
fileAsset =>
fileAsset.metadata.name === asset.metadata.name &&
fileAsset.kind === asset.kind &&
(fileAsset.metadata.namespace || 'default') === (asset.metadata.namespace || 'default') &&
(fileAsset.metadata.version || '1.0') === (asset.metadata.version || '1.0')
);
});
return assetsInThisFile
.map(asset => yaml.dump(asset))
.join('\n---\n');
}
protected isApiValid(api: StudioAsset, relatedAssets: StudioAsset[]): boolean {
for (const asset of relatedAssets) {
if (asset.kind.toLowerCase() === 'freeflowpolicysequence') {
return false;
}
if (asset.kind.toLowerCase() === 'datapowerassembly') {
return false;
}
}
return true;
}
}
/**
* Factory function to create a WMGW transform orchestrator with default registries
* @returns A new WMGW transform orchestrator
*/
export async function createWmgwOrchestrator(): Promise<WmgwTransformerOrchestrator> {
const configLoader: IConfigLoader = new ConfigLoader(await getParentDir())
const configRegistry: IConfigRegistry = {
getConfigPath: (_sourceVersion: string, _targetVersion: string, _kind: string): string | undefined => {
return './configs/skip-transform.json';
}
};
const transformerRegistry: ITransformerRegistry = {
getTransformer: (_name: string): ITransformer | undefined => {
return undefined;
}
};
return new WmgwTransformerOrchestrator(
configRegistry,
transformerRegistry,
configLoader
);
}