@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
279 lines • 10.3 kB
JavaScript
/**
* File Processor Integration
*
* Provides integration between the ProcessorRegistry and message building.
* This module allows for automatic file type detection and processing
* using the registered file processors.
*
* @module processors/integration/FileProcessorIntegration
*
* @example
* ```typescript
* import {
* processFileWithRegistry,
* processBatchWithRegistry,
* getSupportedFileTypes,
* isFileTypeSupported,
* getProcessorForFile,
* } from "./integration/index.js";
*
* // Process a single file
* const { processorName, result } = await processFileWithRegistry(fileInfo);
* if (result?.success) {
* console.log(`Processed with ${processorName}:`, result.data);
* }
*
* // Process multiple files
* const batchResult = await processBatchWithRegistry(files, { maxFiles: 50 });
* console.log(`Successful: ${batchResult.successful.length}`);
* console.log(`Failed: ${batchResult.failed.length}`);
* console.log(`Skipped: ${batchResult.skipped.length}`);
*
* // Check if a file type is supported
* if (isFileTypeSupported("application/pdf", "document.pdf")) {
* console.log("PDF files are supported");
* }
* ```
*/
import { withTimeout } from "../../utils/errorHandling.js";
import { getProcessorRegistry } from "../registry/index.js";
// =============================================================================
// PROCESSING OPTIONS
// =============================================================================
// =============================================================================
// BATCH PROCESSING RESULT
// =============================================================================
// =============================================================================
// SINGLE FILE PROCESSING
// =============================================================================
/**
* Process a single file using the ProcessorRegistry.
* Automatically detects the appropriate processor based on MIME type and filename.
*
* @param fileInfo - File information including content/URL
* @param options - Processing options (preferred processor, auth headers, timeout)
* @returns Object containing processor name (null if none found) and processing result
*
* @example
* ```typescript
* // Basic usage - auto-detect processor
* const { processorName, result } = await processFileWithRegistry({
* id: "file-123",
* name: "document.pdf",
* mimetype: "application/pdf",
* size: 1024000,
* url: "https://example.com/document.pdf",
* });
*
* if (result?.success) {
* console.log(`Processed by ${processorName}:`, result.data);
* }
*
* // Use a specific processor
* const { result } = await processFileWithRegistry(fileInfo, {
* preferredProcessor: "pdf",
* });
*
* // With authentication and timeout
* const { result } = await processFileWithRegistry(fileInfo, {
* authHeaders: { Authorization: "Bearer token123" },
* timeout: 60000,
* });
* ```
*/
export async function processFileWithRegistry(fileInfo, options) {
const registry = await getProcessorRegistry();
const timeout = options?.timeout ?? 30000;
// Use preferred processor if specified
if (options?.preferredProcessor) {
const processor = registry.getProcessor(options.preferredProcessor);
if (processor) {
const result = await withTimeout(processor.processor.processFile(fileInfo, options), timeout, new Error(`File processing timed out after ${timeout}ms`));
return { processorName: options.preferredProcessor, result };
}
}
// Auto-detect processor based on MIME type and filename
const match = registry.findProcessor(fileInfo.mimetype, fileInfo.name);
if (!match) {
return { processorName: null, result: null };
}
const processor = match.processor;
const result = await withTimeout(processor.processFile(fileInfo, options), timeout, new Error(`File processing timed out after ${timeout}ms`));
return { processorName: match.name, result };
}
// =============================================================================
// BATCH FILE PROCESSING
// =============================================================================
/**
* Process multiple files using the ProcessorRegistry.
* Files are processed sequentially and categorized by outcome.
*
* @param files - Array of file information objects
* @param options - Processing options (max files, auth headers, timeout)
* @returns Batch result with successful, failed, and skipped files
*
* @example
* ```typescript
* const files: FileInfo[] = [
* { id: "1", name: "image.jpg", mimetype: "image/jpeg", size: 512000 },
* { id: "2", name: "doc.pdf", mimetype: "application/pdf", size: 1024000 },
* { id: "3", name: "unknown.xyz", mimetype: "application/octet-stream", size: 100 },
* ];
*
* const result = await processBatchWithRegistry(files, {
* maxFiles: 50,
* timeout: 60000,
* });
*
* console.log(`Processed ${result.successful.length} files successfully`);
* console.log(`Failed: ${result.failed.length}`);
* console.log(`Skipped: ${result.skipped.length}`);
*
* // Access individual results
* for (const { fileInfo, processorName, result } of result.successful) {
* console.log(`${fileInfo.name}: ${result.data?.size} bytes`);
* }
* ```
*/
export async function processBatchWithRegistry(files, options) {
const result = {
successful: [],
failed: [],
skipped: [],
};
const maxFiles = options?.maxFiles ?? 100;
const filesToProcess = files.slice(0, maxFiles);
// Process files sequentially
for (const fileInfo of filesToProcess) {
try {
const { processorName, result: processResult } = await processFileWithRegistry(fileInfo, options);
if (!processorName || !processResult) {
// No processor found for this file type
if (!options?.allowFallback) {
result.skipped.push({
fileInfo,
reason: `No processor found for MIME type: ${fileInfo.mimetype}`,
});
}
else {
// allowFallback is true but no fallback processor implemented yet
result.skipped.push({
fileInfo,
reason: `No processor found for MIME type: ${fileInfo.mimetype} (fallback not yet implemented)`,
});
}
continue;
}
if (processResult.success) {
result.successful.push({
fileInfo,
processorName,
result: processResult,
});
}
else {
result.failed.push({
fileInfo,
error: processResult.error?.message || "Unknown error",
});
}
}
catch (error) {
result.failed.push({
fileInfo,
error: error instanceof Error ? error.message : String(error),
});
}
}
// Track skipped files that exceeded the limit
if (files.length > maxFiles) {
for (let i = maxFiles; i < files.length; i++) {
result.skipped.push({
fileInfo: files[i],
reason: `Exceeded maximum file limit (${maxFiles})`,
});
}
}
return result;
}
// =============================================================================
// PROCESSOR DISCOVERY
// =============================================================================
/**
* Get a list of supported file types from the registry.
* Returns information about each registered processor including
* supported MIME types, extensions, and priority.
*
* @returns Array of processor information objects
*
* @example
* ```typescript
* const supportedTypes = getSupportedFileTypes();
*
* for (const { name, mimeTypes, extensions, priority } of supportedTypes) {
* console.log(`${name} (priority: ${priority})`);
* console.log(` MIME types: ${mimeTypes.join(", ")}`);
* console.log(` Extensions: ${extensions.join(", ")}`);
* }
* ```
*/
export async function getSupportedFileTypes() {
const registry = await getProcessorRegistry();
const processors = registry.listProcessors();
return processors.map((p) => ({
name: p.name,
mimeTypes: p.processor.getConfig().supportedMimeTypes || [],
extensions: p.processor.getConfig().supportedExtensions || [],
priority: p.priority,
}));
}
/**
* Check if a file type is supported by any registered processor.
*
* @param mimetype - MIME type of the file
* @param filename - Filename (for extension-based detection)
* @returns true if a processor exists for this file type
*
* @example
* ```typescript
* // Check by MIME type and filename
* if (isFileTypeSupported("application/pdf", "document.pdf")) {
* console.log("PDF files are supported");
* }
*
* // Useful for validation before upload
* function validateFile(file: File): boolean {
* return isFileTypeSupported(file.type, file.name);
* }
* ```
*/
export async function isFileTypeSupported(mimetype, filename) {
const registry = await getProcessorRegistry();
return registry.findProcessor(mimetype, filename) !== null;
}
/**
* Get the processor that would handle a specific file.
* Returns the full processor match including confidence score.
*
* @param mimetype - MIME type of the file
* @param filename - Filename (for extension-based detection)
* @returns Processor match or null if no processor found
*
* @example
* ```typescript
* const match = getProcessorForFile("image/jpeg", "photo.jpg");
*
* if (match) {
* console.log(`Would use ${match.name} processor`);
* console.log(`Priority: ${match.priority}`);
* console.log(`Confidence: ${match.confidence}%`);
* } else {
* console.log("No processor available for this file type");
* }
* ```
*/
export async function getProcessorForFile(mimetype, filename) {
const registry = await getProcessorRegistry();
return registry.findProcessor(mimetype, filename);
}
//# sourceMappingURL=FileProcessorIntegration.js.map