@elephant-xyz/cli
Version: 
CLI tool for Elephant Network
137 lines • 5.13 kB
JavaScript
import { createWriteStream } from 'fs';
import { dirname } from 'path';
import { mkdir } from 'fs/promises';
export class CsvReporterService {
    errorCsvPath;
    warningCsvPath;
    errorStream = null;
    warningStream = null;
    errorCount = 0;
    warningCount = 0;
    startTime;
    constructor(errorCsvPath, warningCsvPath) {
        this.errorCsvPath = errorCsvPath;
        this.warningCsvPath = warningCsvPath;
        this.startTime = new Date();
    }
    async initialize() {
        await this.ensureDirectoriesExist();
        // Initialize CSV streams and write headers, awaiting write completion
        this.errorStream = createWriteStream(this.errorCsvPath, { flags: 'w' });
        await new Promise((resolve, reject) => {
            this.errorStream.write('property_cid,data_group_cid,file_path,error_path,error_message,timestamp\n', (err) => (err ? reject(err) : resolve()));
        });
        this.warningStream = createWriteStream(this.warningCsvPath, { flags: 'w' });
        await new Promise((resolve, reject) => {
            this.warningStream.write('property_cid,data_group_cid,file_path,reason,timestamp\n', (err) => (err ? reject(err) : resolve()));
        });
    }
    async ensureDirectoriesExist() {
        const errorDir = dirname(this.errorCsvPath);
        const warningDir = dirname(this.warningCsvPath);
        await mkdir(errorDir, { recursive: true });
        if (warningDir !== errorDir) {
            await mkdir(warningDir, { recursive: true });
        }
    }
    async logError(entry) {
        if (!this.errorStream) {
            throw new Error('CSV reporter not initialized. Call initialize() first.');
        }
        const escapedErrorPath = this.escapeCsvValue(entry.errorPath);
        const escapedErrorMessage = this.escapeCsvValue(entry.errorMessage);
        const escapedFilePath = this.escapeCsvValue(entry.filePath);
        const csvLine = `${entry.propertyCid},${entry.dataGroupCid},${escapedFilePath},${escapedErrorPath},${escapedErrorMessage},${entry.timestamp}\n`;
        return new Promise((resolve, reject) => {
            this.errorStream.write(csvLine, (error) => {
                if (error) {
                    reject(error);
                }
                else {
                    this.errorCount++;
                    resolve();
                }
            });
        });
    }
    async logWarning(entry) {
        if (!this.warningStream) {
            throw new Error('CSV reporter not initialized. Call initialize() first.');
        }
        const escapedReason = this.escapeCsvValue(entry.reason);
        const escapedFilePath = this.escapeCsvValue(entry.filePath);
        const csvLine = `${entry.propertyCid},${entry.dataGroupCid},${escapedFilePath},${escapedReason},${entry.timestamp}\n`;
        return new Promise((resolve, reject) => {
            this.warningStream.write(csvLine, (error) => {
                if (error) {
                    reject(error);
                }
                else {
                    this.warningCount++;
                    resolve();
                }
            });
        });
    }
    escapeCsvValue(value) {
        // Escape double quotes by doubling them
        const escaped = value.replace(/"/g, '""');
        // Wrap in quotes if contains comma, newline, or quotes
        if (escaped.includes(',') ||
            escaped.includes('\n') ||
            escaped.includes('"')) {
            return `"${escaped}"`;
        }
        return escaped;
    }
    async finalize() {
        const endTime = new Date();
        // Close streams
        await this.closeStreams();
        const summary = {
            totalFiles: 0, // Will be set by caller
            processedFiles: 0, // Will be set by caller
            errorCount: this.errorCount,
            warningCount: this.warningCount,
            uploadedFiles: 0, // Will be set by caller
            submittedBatches: 0, // Will be set by caller
            startTime: this.startTime,
            endTime,
            duration: endTime.getTime() - this.startTime.getTime(),
        };
        return summary;
    }
    async closeStreams() {
        const promises = [];
        if (this.errorStream) {
            promises.push(new Promise((resolve, reject) => {
                this.errorStream.end((error) => {
                    if (error)
                        reject(error);
                    else
                        resolve();
                });
            }));
        }
        if (this.warningStream) {
            promises.push(new Promise((resolve, reject) => {
                this.warningStream.end((error) => {
                    if (error)
                        reject(error);
                    else
                        resolve();
                });
            }));
        }
        await Promise.all(promises);
        this.errorStream = null;
        this.warningStream = null;
    }
    getErrorCount() {
        return this.errorCount;
    }
    getWarningCount() {
        return this.warningCount;
    }
}
//# sourceMappingURL=csv-reporter.service.js.map