UNPKG

@apistudio/apim-cli

Version:

CLI for API Management Products

185 lines (155 loc) 5.81 kB
import * as path from 'path'; import * as fs from 'fs/promises'; import { AbstractInventoryBuilder } from '../src/core/design/AbstractInventoryBuilder.js'; import * as yaml from 'js-yaml'; // Define the categories for organizing schemas const COMMON_SCHEMAS = ['api', 'urischemes', 'cors', 'properties', 'scope', 'product', 'plan', 'quota']; interface SchemaInfo { name: string; version: string; content: string; category: 'common' | 'policies'; fileType: 'ts' | 'yaml'; } class InventoryGenerator extends AbstractInventoryBuilder { async generateInventoryModule(outputPath: string): Promise<void> { try { // Ensure the output directory exists await fs.mkdir(path.join(outputPath, 'generated/source/assets/common'), { recursive: true }); await fs.mkdir(path.join(outputPath, 'generated/source/assets/policies'), { recursive: true }); // Process each source path from the config for (const sourcePath of this.config.source) { if (sourcePath) { await this.processSourcePath(sourcePath, outputPath); } } console.log(`Inventory generation completed at ${outputPath}`); } catch (error) { console.error('Error generating inventory:', error); throw error; } } private async processSourcePath(sourcePath: string, outputBasePath: string): Promise<void> { try { // Resolve the full path const fullPath = path.resolve(process.cwd(), sourcePath.startsWith('/') ? `.${sourcePath}` : sourcePath); // const fullPath = '/Users/sowbarnigaa/Documents/pocs/Smith/smith/packages/schema-specification/V12_openAPI_specification.yaml'; console.log(`Processing source path: ${fullPath}`); // Check if the file exists try { await fs.access(fullPath); } catch (error) { console.warn(`Source file not found: ${fullPath}`); return; } // Read the file content const content = await fs.readFile(fullPath, 'utf8'); // Determine file type and parse accordingly const isYaml = fullPath.endsWith('.yaml') || fullPath.endsWith('.yml'); let schemas; if (isYaml) { const parsed = yaml.load(content) as any; schemas = parsed.components?.schemas; } else { // Assume JSON const parsed = JSON.parse(content); schemas = parsed.components?.schemas || parsed.schemas; } if (!schemas) { console.warn(`No schemas found in ${fullPath}`); return; } // Process each schema for (const [schemaName, schema] of Object.entries<any>(schemas)) { await this.processSchema(schemaName, schema, outputBasePath, isYaml ? 'yaml' : 'ts'); } } catch (error) { console.error(`Error processing source path ${sourcePath}:`, error); throw error; } } private async processSchema( schemaName: string, schema: any, outputBasePath: string, fileType: 'ts' | 'yaml' ): Promise<void> { try { // Extract schema information const schemaInfo = this.extractSchemaInfo(schemaName, schema, fileType); if (!schemaInfo) { console.warn(`Could not extract information for schema: ${schemaName}`); return; } // Determine the output directory const baseDir = path.join( outputBasePath, 'generated/source/assets', schemaInfo.category, schemaInfo.name.toLowerCase() ); // Create the directory if it doesn't exist await fs.mkdir(baseDir, { recursive: true }); // Create the output file const fileName = `${schemaInfo.version.replace('\\', '-').replace('/', '-')}_${schemaInfo.name.toLowerCase()}.json`; const filePath = path.join(baseDir, fileName); await fs.writeFile(filePath, schemaInfo.content, 'utf8'); console.log(`Generated: ${filePath}`); } catch (error) { console.error(`Error processing schema ${schemaName}:`, error); throw error; } } private extractSchemaInfo( schemaName: string, schema: any, fileType: 'ts' | 'yaml' ): SchemaInfo | null { try { // Determine the category (common or policies) const category = this.getCategory(schemaName); // Extract the version from the schema const version = this.extractVersion(schema) || 'api.ibm.com-v1'; // Convert schema to string content const content = typeof schema === 'string' ? schema : JSON.stringify(schema, null, 2); return { name: schemaName, version, content, category, fileType: fileType }; } catch (error) { console.error(`Error extracting schema info for ${schemaName}:`, error); return null; } } private getCategory(schemaName: string): 'common' | 'policies' { const lowerName = schemaName.toLowerCase(); return COMMON_SCHEMAS.some(common => lowerName === common.toLowerCase()) ? 'common' : 'policies'; } private extractVersion(schema: any): string | null { // Try to extract version from different possible locations if (schema.apiVersion?.default) { return schema.apiVersion.default; } if (schema.properties?.apiVersion?.default) { return schema.properties.apiVersion.default; } // If no version found, return null return null; } } async function run() { const configPath = path.join(process.cwd(), 'generator/inventory_config.json'); const outputPath = process.cwd(); const generator = new InventoryGenerator(); await generator.runGeneration(configPath, outputPath); console.log(`Inventory generation completed at ${outputPath}`); } // Run the generator run().catch(err => { console.error('Inventory generation failed:', err); process.exit(1); }); // Made with Bob