UNPKG

credl-parser-evaluator

Version:

TypeScript-based CREDL Parser and Evaluator that processes CREDL files and outputs complete Intermediate Representations

285 lines • 13.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.createConvertCommand = createConvertCommand; exports.executeConvertCommand = executeConvertCommand; const commander_1 = require("commander"); const index_js_1 = require("../../api/index.js"); const path = __importStar(require("path")); const fs = __importStar(require("fs/promises")); // Error exit codes for different types of failures var ExitCode; (function (ExitCode) { ExitCode[ExitCode["SUCCESS"] = 0] = "SUCCESS"; ExitCode[ExitCode["VALIDATION_ERROR"] = 1] = "VALIDATION_ERROR"; ExitCode[ExitCode["FILE_NOT_FOUND"] = 2] = "FILE_NOT_FOUND"; ExitCode[ExitCode["FILE_ACCESS_ERROR"] = 3] = "FILE_ACCESS_ERROR"; ExitCode[ExitCode["PARSING_ERROR"] = 4] = "PARSING_ERROR"; ExitCode[ExitCode["OUTPUT_ERROR"] = 5] = "OUTPUT_ERROR"; ExitCode[ExitCode["INVALID_ARGUMENTS"] = 6] = "INVALID_ARGUMENTS"; ExitCode[ExitCode["GENERAL_ERROR"] = 10] = "GENERAL_ERROR"; })(ExitCode || (ExitCode = {})); function createConvertCommand() { const convertCommand = new commander_1.Command('convert'); convertCommand .description('Convert CREDL files to Intermediate Representation (IR)') .argument('<file>', 'Path to the CREDL file to convert') .option('-o, --output <path>', 'Output file path (default: console output)') .option('-f, --format <format>', 'Output format: json, pretty', 'pretty') .option('-q, --quiet', 'Suppress output except errors') .option('-v, --verbose', 'Verbose output with detailed processing information') .option('--fail-fast', 'Stop processing on first validation error') .option('--include-metadata', 'Include processing metadata in IR', true) .option('--resolve-presets', 'Resolve preset references', true) .option('--resolve-templates', 'Resolve template definitions', true) .option('--validate-references', 'Validate cross-references', true) .option('--generate-ids', 'Generate unique IDs for elements', true) .option('--skip-validation', 'Skip validation and generate IR from parsed content') .action(async (filePath, options) => { await executeConvertCommand(filePath, options); }); return convertCommand; } async function executeConvertCommand(filePath, options) { try { // Validate file path and existence await validateInputFile(filePath, options); if (!options.quiet) { console.log(`šŸ”„ Converting CREDL file to IR: ${filePath}`); } // Configure validation options const validationOptions = { failFast: options['fail-fast'] || false, checkCrossReferences: options['validate-references'] !== false, strict: false // Convert command uses standard validation by default }; // Configure IR builder options const irOptions = { includeMetadata: options['include-metadata'] !== false, resolvePresets: options['resolve-presets'] !== false, resolveTemplates: options['resolve-templates'] !== false, validateReferences: options['validate-references'] !== false, generateIds: options['generate-ids'] !== false }; if (options.verbose) { console.log('šŸ“‹ Conversion Configuration:'); console.log(` • Skip validation: ${options['skip-validation'] ? 'yes' : 'no'}`); console.log(` • Presets: ${irOptions.resolvePresets ? 'enabled' : 'disabled'}`); console.log(` • Templates: ${irOptions.resolveTemplates ? 'enabled' : 'disabled'}`); console.log(` • Cross-references: ${irOptions.validateReferences ? 'enabled' : 'disabled'}`); console.log(` • Generate IDs: ${irOptions.generateIds ? 'enabled' : 'disabled'}`); console.log(` • Output format: ${options.format}`); } // Convert CREDL to IR with progress indicators const startTime = Date.now(); if (options.verbose) { console.log('šŸ”„ Starting CREDL to IR conversion pipeline...'); process.stdout.write(' šŸ“ Parsing CREDL file... '); } // Step 1: Read and parse CREDL file const fileContent = await fs.readFile(filePath, 'utf8'); const credlFile = await (0, index_js_1.parse)(fileContent); if (options.verbose) { console.log('āœ…'); process.stdout.write(' šŸ” Validating structure... '); } // Step 2: Validate if not skipping validation if (!options['skip-validation']) { const validationResult = await (0, index_js_1.validate)(credlFile, validationOptions); if (!validationResult.isValid) { const errorDetails = validationResult.errors.map(error => `${error.field}: ${error.message}`).join('\n • '); console.error(`āŒ Validation failed, cannot generate IR:\n • ${errorDetails}`); console.error('\nšŸ’” Suggestions:'); console.error(' • Review the CREDL specification to fix validation errors'); console.error(' • Use --skip-validation to generate IR despite validation errors'); console.error(' • Use --verbose flag for more detailed error information'); process.exit(ExitCode.VALIDATION_ERROR); } if (options.verbose && validationResult.warnings.length > 0) { console.log(`āš ļø (${validationResult.warnings.length} warnings)`); } else if (options.verbose) { console.log('āœ…'); } } else if (options.verbose) { console.log('ā­ļø (skipped)'); } if (options.verbose) { process.stdout.write(' šŸ—ļø Generating IR... '); } // Step 3: Generate IR const ir = await (0, index_js_1.generateIR)(credlFile, irOptions); const processingTime = Date.now() - startTime; if (options.verbose) { console.log('āœ…'); console.log(` šŸŽÆ Conversion completed successfully`); } if (options.verbose) { console.log(`ā±ļø Processing completed in ${processingTime}ms`); console.log(`šŸ“Š Generated IR:`); console.log(` • Assets: ${ir.assets.length}`); console.log(` • Spaces: ${ir.spaces.length}`); console.log(` • Template-generated spaces: ${ir.template_generated_spaces?.length || 0}`); console.log(` • Assumptions: ${ir.assumptions.length}`); console.log(` • Models: ${ir.models.length}`); console.log(` • Resolution steps: ${ir.resolution_order.length}`); if (ir.validation.warnings.length > 0) { console.log(` • Warnings: ${ir.validation.warnings.length}`); } } // Format and output IR if (options.verbose) { process.stdout.write(' �� Formatting IR output... '); } const outputContent = formatIROutput(ir, options.format || 'pretty'); if (options.verbose) { console.log('āœ…'); } if (options.output) { try { if (options.verbose) { process.stdout.write(' šŸ’¾ Writing IR to file... '); } // Create output directory if it doesn't exist const outputDir = path.dirname(options.output); await fs.mkdir(outputDir, { recursive: true }); // Write to file await fs.writeFile(options.output, outputContent, 'utf8'); if (options.verbose) { console.log('āœ…'); } if (!options.quiet) { console.log(`āœ… IR written to: ${options.output}`); } } catch (writeError) { console.error(`āŒ Failed to write IR to file: ${options.output}`); console.error(` Error: ${writeError instanceof Error ? writeError.message : String(writeError)}`); process.exit(ExitCode.OUTPUT_ERROR); } } else { // Output to console if (!options.quiet && options.format !== 'json') { console.log('šŸ“‹ Generated IR:'); } console.log(outputContent); } if (!options.quiet) { console.log(`āœ… Successfully converted CREDL to IR in ${processingTime}ms`); } } catch (error) { console.error('āŒ Error converting CREDL to IR:'); if (error instanceof Error) { console.error(` ${error.message}`); if (options.verbose && error.stack) { console.error('\nšŸ› Stack trace:'); console.error(error.stack); } } else { console.error(` ${String(error)}`); } process.exit(ExitCode.GENERAL_ERROR); } } async function validateInputFile(filePath, options) { // Check if file path is provided if (!filePath || filePath.trim().length === 0) { console.error('āŒ No file path provided'); console.error('\nšŸ’” Suggestions:'); console.error(' • Provide a path to a CREDL file as an argument'); console.error(' • Example: credl convert my-file.credl'); process.exit(ExitCode.INVALID_ARGUMENTS); } // Resolve the file path const resolvedPath = path.resolve(filePath); if (options.verbose) { console.log(`šŸ“ Validating file: ${resolvedPath}`); } // Check if file exists const fileExists = await (0, index_js_1.checkFileExists)(resolvedPath); if (!fileExists) { console.error(`āŒ File not found: ${filePath}`); console.error(` Resolved path: ${resolvedPath}`); console.error('\nšŸ’” Suggestions:'); console.error(' • Check if the file path is correct'); console.error(' • Ensure the file exists'); console.error(' • Try using an absolute path'); process.exit(ExitCode.FILE_NOT_FOUND); } // Get file stats and validate const fileStats = await (0, index_js_1.getFileStats)(resolvedPath); if (!fileStats) { console.error(`āŒ Cannot access file: ${filePath}`); console.error('\nšŸ’” Suggestions:'); console.error(' • Check if you have permission to read the file'); console.error(' • Ensure the file is not locked by another process'); process.exit(ExitCode.FILE_ACCESS_ERROR); } // Check if it's a regular file (not a directory) if (fileStats.size === 0) { console.error(`āŒ File is empty: ${filePath}`); console.error('\nšŸ’” Suggestions:'); console.error(' • Ensure the file contains valid CREDL content'); console.error(' • Check if the file was saved properly'); process.exit(ExitCode.PARSING_ERROR); } // Validate file extension (optional warning) const fileExtension = path.extname(filePath).toLowerCase(); const validExtensions = ['.credl', '.yaml', '.yml']; if (!validExtensions.includes(fileExtension) && !options.quiet) { console.warn(`āš ļø Warning: File extension '${fileExtension}' is not typical for CREDL files`); console.warn(` Expected extensions: ${validExtensions.join(', ')}`); } if (options.verbose) { console.log(`āœ… File validation passed:`); console.log(` • File size: ${fileStats.size} bytes`); console.log(` • Last modified: ${fileStats.modified.toISOString()}`); console.log(` • Extension: ${fileExtension || '(none)'}`); } } function formatIROutput(ir, format) { switch (format) { case 'json': return JSON.stringify(ir); case 'pretty': default: return JSON.stringify(ir, null, 2); } } //# sourceMappingURL=convert.js.map