{"version":3,"sources":["../src/core/file-processor.ts"],"names":["FileProcessor","_FileProcessor","options","__publicField","FILE_SIZE","files","validation","InputValidator","processedFiles","errors","file","result","error","errorMessage","preview","warnings","maxSizeMB","fileSizeMB","type","category","resolve","reject","reader","timestamp","random","extension","bytes","k","sizes","filename","parts","dangerousExtensions","ext"],"mappings":"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","file":"chunk-YZAKDUU2.cjs","sourcesContent":["import type {\r\n  UploadFile,\r\n  UploadOptions,\r\n  FileValidationResult,\r\n  FileProcessingResult,\r\n} from \"../types\";\r\nimport { FILE_SIZE } from \"./config\";\r\nimport { InputValidator } from \"./validation\";\r\n\r\n/**\r\n * Enhanced file processor with comprehensive validation and error handling\r\n * Provider-agnostic and highly configurable\r\n */\r\nexport class FileProcessor {\r\n  private readonly options: Required<\r\n    Omit<\r\n      UploadOptions,\r\n      | \"folder\"\r\n      | \"onProgress\"\r\n      | \"onSuccess\"\r\n      | \"onError\"\r\n      | \"onCancel\"\r\n      | \"metadata\"\r\n      | \"tags\"\r\n    >\r\n  >;\r\n\r\n  constructor(options: UploadOptions = {}) {\r\n    this.options = {\r\n      maxFiles: options.maxFiles || 10,\r\n      maxFileSize: options.maxFileSize || FILE_SIZE.DEFAULT_MAX_SIZE,\r\n      allowedTypes: options.allowedTypes || [\r\n        \"image/*\",\r\n        \"application/pdf\",\r\n        \"text/*\",\r\n      ],\r\n    };\r\n  }\r\n\r\n  /**\r\n   * Process and validate multiple files with comprehensive error handling\r\n   */\r\n  async processFiles(files: readonly File[]): Promise<FileProcessingResult> {\r\n    // Validate input files\r\n    const validation = InputValidator.validateFileList(files as File[]);\r\n    if (!validation.isValid) {\r\n      return {\r\n        success: false,\r\n        errors: validation.errors,\r\n      };\r\n    }\r\n\r\n    if (!files.length) {\r\n      return { success: true, files: [] };\r\n    }\r\n\r\n    if (files.length > this.options.maxFiles) {\r\n      return {\r\n        success: false,\r\n        errors: [\r\n          `Maximum ${this.options.maxFiles} files allowed. Received ${files.length} files.`,\r\n        ],\r\n      };\r\n    }\r\n\r\n    const processedFiles: UploadFile[] = [];\r\n    const errors: string[] = [];\r\n\r\n    for (const file of files) {\r\n      try {\r\n        const result = await this.processFile(file);\r\n        if (result.success && result.file) {\r\n          processedFiles.push(result.file);\r\n        } else if (result.error) {\r\n          errors.push(result.error);\r\n        }\r\n      } catch (error) {\r\n        const errorMessage =\r\n          error instanceof Error ? error.message : \"Unknown error occurred\";\r\n        errors.push(`Failed to process ${file.name}: ${errorMessage}`);\r\n      }\r\n    }\r\n\r\n    return {\r\n      success: processedFiles.length > 0,\r\n      files: processedFiles,\r\n      errors: errors.length > 0 ? errors : undefined,\r\n    };\r\n  }\r\n\r\n  /**\r\n   * Process a single file with comprehensive validation\r\n   */\r\n  private async processFile(\r\n    file: File\r\n  ): Promise<{ success: boolean; file?: UploadFile; error?: string }> {\r\n    // Validate file\r\n    const validation = this.validateFile(file);\r\n    if (!validation.valid) {\r\n      return { success: false, error: validation.error || \"Validation failed\" };\r\n    }\r\n\r\n    // Generate preview for images\r\n    let preview: string | undefined;\r\n    if (FileProcessor.isImage(file.type)) {\r\n      try {\r\n        preview = await this.generatePreview(file);\r\n      } catch (error) {\r\n        console.warn(`Failed to generate preview for ${file.name}:`, error);\r\n        // Continue without preview - not a critical error\r\n      }\r\n    }\r\n\r\n    const processedFile: UploadFile = {\r\n      id: this.generateFileId(file),\r\n      file,\r\n      name: file.name,\r\n      size: file.size,\r\n      type: file.type,\r\n      preview,\r\n      progress: 0,\r\n      status: \"pending\",\r\n    };\r\n\r\n    return { success: true, file: processedFile };\r\n  }\r\n\r\n  /**\r\n   * Comprehensive file validation with detailed error messages\r\n   */\r\n  private validateFile(file: File): FileValidationResult {\r\n    const warnings: string[] = [];\r\n\r\n    // Check file size\r\n    if (file.size > this.options.maxFileSize) {\r\n      const maxSizeMB = Math.round(\r\n        this.options.maxFileSize / FILE_SIZE.BYTES_PER_MB\r\n      );\r\n      const fileSizeMB = Math.round(file.size / FILE_SIZE.BYTES_PER_MB);\r\n      return {\r\n        valid: false,\r\n        error: `File \"${file.name}\" is too large. Maximum size: ${maxSizeMB}MB, Received: ${fileSizeMB}MB`,\r\n      };\r\n    }\r\n\r\n    // Check file type\r\n    if (this.options.allowedTypes.length > 0) {\r\n      const isValidType = this.options.allowedTypes.some((type) => {\r\n        if (type === \"*\") return true;\r\n        if (type.endsWith(\"/*\")) {\r\n          const category = type.split(\"/\")[0];\r\n          return file.type.startsWith(category + \"/\");\r\n        }\r\n        if (type.startsWith(\".\")) {\r\n          return file.name.toLowerCase().endsWith(type.toLowerCase());\r\n        }\r\n        return file.type === type;\r\n      });\r\n\r\n      if (!isValidType) {\r\n        return {\r\n          valid: false,\r\n          error: `File type \"${\r\n            file.type\r\n          }\" not allowed. Allowed types: ${this.options.allowedTypes.join(\r\n            \", \"\r\n          )}`,\r\n        };\r\n      }\r\n    }\r\n\r\n    // Additional validations\r\n    if (file.size === 0) {\r\n      warnings.push(\"File appears to be empty\");\r\n    }\r\n\r\n    if (file.name.length > 255) {\r\n      warnings.push(\"Filename is very long\");\r\n    }\r\n\r\n    return {\r\n      valid: true,\r\n      warnings: warnings.length > 0 ? warnings : undefined,\r\n    };\r\n  }\r\n\r\n  /**\r\n   * Generate preview for image files with error handling\r\n   */\r\n  private generatePreview(file: File): Promise<string> {\r\n    return new Promise((resolve, reject) => {\r\n      if (!FileProcessor.isImage(file.type)) {\r\n        reject(new Error(\"Preview only available for image files\"));\r\n        return;\r\n      }\r\n\r\n      const reader = new FileReader();\r\n      reader.onload = () => {\r\n        const result = reader.result;\r\n        if (typeof result === \"string\") {\r\n          resolve(result);\r\n        } else {\r\n          reject(new Error(\"Failed to generate preview\"));\r\n        }\r\n      };\r\n      reader.onerror = () =>\r\n        reject(new Error(\"Failed to read file for preview\"));\r\n      reader.readAsDataURL(file);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Generate unique file ID with collision resistance\r\n   */\r\n  private generateFileId(file: File): string {\r\n    const timestamp = Date.now();\r\n    const random = Math.random().toString(36).substring(2, 15);\r\n    const extension = file.name.split(\".\").pop() || \"\";\r\n    const sanitizedName = file.name\r\n      .replace(/[^a-zA-Z0-9]/g, \"_\")\r\n      .substring(0, 20);\r\n\r\n    return `${sanitizedName}_${timestamp}_${random}${\r\n      extension ? `.${extension}` : \"\"\r\n    }`;\r\n  }\r\n\r\n  // Static utility methods\r\n  /**\r\n   * Format file size for human-readable display\r\n   */\r\n  static formatFileSize(bytes: number): string {\r\n    if (bytes === 0) return \"0 Bytes\";\r\n\r\n    const k = FILE_SIZE.BYTES_PER_KB;\r\n    const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\"] as const;\r\n    const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n\r\n    if (i >= sizes.length)\r\n      return `${(bytes / Math.pow(k, sizes.length - 1)).toFixed(2)} TB`;\r\n\r\n    return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\r\n  }\r\n\r\n  /**\r\n   * Get appropriate file icon based on MIME type\r\n   */\r\n  static getFileIcon(type: string): string {\r\n    if (FileProcessor.isImage(type)) return \"🖼️\";\r\n    if (FileProcessor.isVideo(type)) return \"🎥\";\r\n    if (FileProcessor.isAudio(type)) return \"🎵\";\r\n    if (FileProcessor.isDocument(type)) return \"📄\";\r\n    if (FileProcessor.isArchive(type)) return \"📦\";\r\n    if (FileProcessor.isCode(type)) return \"💻\";\r\n    return \"📁\";\r\n  }\r\n\r\n  /**\r\n   * Type checking methods with better accuracy\r\n   */\r\n  static isImage(type: string): boolean {\r\n    return type.startsWith(\"image/\");\r\n  }\r\n\r\n  static isVideo(type: string): boolean {\r\n    return type.startsWith(\"video/\");\r\n  }\r\n\r\n  static isAudio(type: string): boolean {\r\n    return type.startsWith(\"audio/\");\r\n  }\r\n\r\n  static isDocument(type: string): boolean {\r\n    return (\r\n      (type.startsWith(\"text/\") &&\r\n        !type.includes(\"javascript\") &&\r\n        !type.includes(\"typescript\")) ||\r\n      type === \"application/pdf\" ||\r\n      type.includes(\"document\") ||\r\n      type.includes(\"word\") ||\r\n      type.includes(\"excel\") ||\r\n      type.includes(\"powerpoint\") ||\r\n      type.includes(\"presentation\")\r\n    );\r\n  }\r\n\r\n  static isArchive(type: string): boolean {\r\n    return (\r\n      type.includes(\"zip\") ||\r\n      type.includes(\"rar\") ||\r\n      type.includes(\"tar\") ||\r\n      type.includes(\"7z\") ||\r\n      type.includes(\"gzip\") ||\r\n      type.includes(\"bzip2\")\r\n    );\r\n  }\r\n\r\n  static isCode(type: string): boolean {\r\n    return (\r\n      type.includes(\"javascript\") ||\r\n      type.includes(\"typescript\") ||\r\n      type.includes(\"python\") ||\r\n      type.includes(\"java\") ||\r\n      type.includes(\"c++\") ||\r\n      type.includes(\"c#\") ||\r\n      type.includes(\"php\") ||\r\n      type.includes(\"ruby\") ||\r\n      type.includes(\"go\") ||\r\n      type.includes(\"rust\") ||\r\n      type.includes(\"swift\") ||\r\n      type.includes(\"kotlin\") ||\r\n      type.includes(\"x-python\") ||\r\n      type.includes(\"x-java\") ||\r\n      type.includes(\"x-c++\") ||\r\n      type.includes(\"x-c#\") ||\r\n      type.includes(\"x-php\") ||\r\n      type.includes(\"x-ruby\") ||\r\n      type.includes(\"x-go\") ||\r\n      type.includes(\"x-rust\") ||\r\n      type.includes(\"x-swift\") ||\r\n      type.includes(\"x-kotlin\")\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Get file category for better organization\r\n   */\r\n  static getFileCategory(\r\n    type: string\r\n  ): \"image\" | \"video\" | \"audio\" | \"document\" | \"archive\" | \"code\" | \"other\" {\r\n    if (FileProcessor.isImage(type)) return \"image\";\r\n    if (FileProcessor.isVideo(type)) return \"video\";\r\n    if (FileProcessor.isAudio(type)) return \"audio\";\r\n    if (FileProcessor.isDocument(type)) return \"document\";\r\n    if (FileProcessor.isArchive(type)) return \"archive\";\r\n    if (FileProcessor.isCode(type)) return \"code\";\r\n    return \"other\";\r\n  }\r\n\r\n  /**\r\n   * Get file extension from filename\r\n   */\r\n  static getFileExtension(filename: string): string {\r\n    const parts = filename.split(\".\");\r\n    return parts.length > 1 ? parts.pop()?.toLowerCase() || \"\" : \"\";\r\n  }\r\n\r\n  /**\r\n   * Check if file is potentially dangerous\r\n   */\r\n  static isPotentiallyDangerous(filename: string): boolean {\r\n    const dangerousExtensions = [\r\n      \"exe\",\r\n      \"bat\",\r\n      \"cmd\",\r\n      \"com\",\r\n      \"pif\",\r\n      \"scr\",\r\n      \"vbs\",\r\n      \"js\",\r\n      \"jar\",\r\n      \"msi\",\r\n      \"ps1\",\r\n      \"psm1\",\r\n      \"psd1\",\r\n      \"ps1xml\",\r\n      \"psc1\",\r\n      \"psc2\",\r\n      \"py\",\r\n      \"pyc\",\r\n      \"pyw\",\r\n    ];\r\n    const ext = FileProcessor.getFileExtension(filename);\r\n    return dangerousExtensions.includes(ext);\r\n  }\r\n}\r\n"]}