UNPKG

@juspay/neurolink

Version:

Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio

178 lines 5.35 kB
/** * Audio file utilities for CLI * * Provides functionality for saving TTS audio to files with proper * error handling and directory creation. * * @module cli/utils/audioFileUtils */ import fs from "fs"; import path from "path"; /** * Format file size in human-readable format * * @param bytes - Size in bytes * @returns Formatted string (e.g., "32 KB", "1.5 MB") */ export function formatFileSize(bytes) { if (bytes < 1024) { return `${bytes} B`; } else if (bytes < 1024 * 1024) { return `${(bytes / 1024).toFixed(1)} KB`; } else if (bytes < 1024 * 1024 * 1024) { return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; } else { return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`; } } /** * Resolve the output path, handling both absolute and relative paths * * @param outputPath - User-specified output path * @returns Resolved absolute path */ export function resolveOutputPath(outputPath) { if (path.isAbsolute(outputPath)) { return outputPath; } return path.resolve(process.cwd(), outputPath); } /** * Ensure parent directories exist, creating them if necessary * * @param filePath - Full path to the file */ export async function ensureDirectoryExists(filePath) { const directory = path.dirname(filePath); try { await fs.promises.access(directory, fs.constants.F_OK); } catch { // Directory doesn't exist, create it recursively await fs.promises.mkdir(directory, { recursive: true }); } } /** * Get appropriate file extension for audio format * * @param format - Audio format * @returns File extension (including dot) */ export function getAudioExtension(format) { switch (format) { case "mp3": return ".mp3"; case "wav": return ".wav"; case "ogg": return ".ogg"; case "opus": return ".opus"; case "pcm16": // Raw PCM16 (no RIFF/WAV header) — write to .pcm so consumers don't // mistake it for a parseable WAV file. return ".pcm"; default: return ".mp3"; } } /** * Validate and normalize output path, adding extension if needed * * @param outputPath - User-specified output path * @param format - Audio format for extension * @returns Normalized output path */ export function normalizeOutputPath(outputPath, format = "mp3") { const resolvedPath = resolveOutputPath(outputPath); const ext = path.extname(resolvedPath).toLowerCase(); // If no extension or wrong extension, add the correct one const validExtensions = [".mp3", ".wav", ".ogg", ".opus", ".pcm"]; if (!ext || !validExtensions.includes(ext)) { return resolvedPath + getAudioExtension(format); } return resolvedPath; } /** * Save TTS audio result to a file * * Creates parent directories if they don't exist and handles both * absolute and relative paths. * * @param audio - TTS result containing audio buffer * @param outputPath - Path where the audio should be saved * @returns Save result with success status, path, and size * * @example * ```typescript * const result = await saveAudioToFile(audioResult, "./output/audio.mp3"); * if (result.success) { * console.log(`Saved to ${result.path} (${formatFileSize(result.size)})`); * } * ``` */ export async function saveAudioToFile(audio, outputPath) { try { // Normalize the output path const normalizedPath = normalizeOutputPath(outputPath, audio.format); // Ensure parent directories exist await ensureDirectoryExists(normalizedPath); // Write the audio buffer to file await fs.promises.writeFile(normalizedPath, audio.buffer); // Get the actual file size const stats = await fs.promises.stat(normalizedPath); return { success: true, path: normalizedPath, size: stats.size, }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "Unknown error occurred"; return { success: false, path: outputPath, size: 0, error: errorMessage, }; } } /** * Validate that a path is writable * * @param filePath - Path to validate * @returns True if the path is writable */ export async function isPathWritable(filePath) { try { const resolvedPath = resolveOutputPath(filePath); const directory = path.dirname(resolvedPath); // Check if directory exists try { await fs.promises.access(directory, fs.constants.W_OK); return true; } catch { // Directory doesn't exist, check if we can create it // by checking write access to the nearest existing parent let parentDir = directory; while (parentDir !== path.dirname(parentDir)) { try { await fs.promises.access(parentDir, fs.constants.W_OK); return true; } catch { parentDir = path.dirname(parentDir); } } return false; } } catch { return false; } } //# sourceMappingURL=audioFileUtils.js.map