UNPKG

s3-file-manager

Version:

A streamlined, high-level S3 client for Node.js with built-in retries and support for uploads, downloads, and file operations — works with any S3-compatible storage.

235 lines (234 loc) 13.8 kB
import { S3FMContext } from "./core/context.js"; import { UploadManager } from "./core/uploadManager.js"; import { FileService } from "./core/fileService.js"; import { DownloadManager } from "./core/downloadManager.js"; /** * ╔════════════════════════════════════════════════════════════════════════════╗ * ║ 📦 S3 FILE MANAGER ║ * ║ Primary facade class for interacting with S3. Provides unified public ║ * ║ methods for uploading, downloading, and inspecting files. ║ * ║ Internally delegates to UploadManager, DownloadManager, and FileService. ║ * ╚════════════════════════════════════════════════════════════════════════════╝ */ export class S3FileManager { sharedContext; uploads; downloads; services; constructor(config) { this.sharedContext = new S3FMContext(config); this.uploads = new UploadManager(this.sharedContext, config.maxUploadConcurrency); this.downloads = new DownloadManager(this.sharedContext); this.services = new FileService(this.sharedContext); } /** ╔════════════════════════════════════════════════════════════════════════════════╗ ║ 🧾 FILE SERVICE ║ ║ Public-facing interface for loading, saving, or transferring file data ║ ║ through the S3 storage layer. Orchestrates upload/download logic. ║ ╚════════════════════════════════════════════════════════════════════════════════╝ */ /** * Lists all files in the S3 bucket or under a given prefix in the S3 bucket. * @param prefix - The S3 prefix under which to search * @param options - Optional settings including filter and compare functions and tracing span settings. * If prefix is not supplied, all file paths in bucket are listed. * @returns A promise resolving to an array of file paths. */ async listFiles(prefix, options) { return this.services.listFiles(prefix, options); } /** * Lists all directories (common prefixes) in the S3 bucket or within a given prefix in the S3 bucket. * @param prefix - The S3 prefix under which to search * @param options - Optional settings including filter and compare functions and tracing span settings. * If prefix is not supplied, all directories in bucket are listed. * @returns Promise resolving to an array of directory names (prefixes). */ async listFolders(prefix, options) { return this.services.listFolders(prefix, options); } /** * Verifies the existence of multiple files in the S3 bucket. * @param filePaths - An array of S3 file paths to check. * @param options - Optional settings including prefix and tracing span settings. * @returns A promise resolving to an array of missing file paths. */ async verifyFilesExist(filenames, options) { if (options) { delete options.bucketName; } return this.services.verifyFilesExist(filenames, options); } /** * Copies a file from one location to another within the same bucket or from a different bucket to the current bucket. * Optionally allows renaming the file during the copy operation. * @param filePath - Path to the file in the bucket to copy. * @param destinationPrefix - The prefix to copy the file to. * @param options - Optional settings including source bucket name and tracing span settings. * @returns A promise resolving to a CopyReturnType object indicating success, source path, and destination path. */ async copyFile(filePath, destinationPrefix, options) { if (options) { delete options.newFilename; } return await this.services.copyFile(filePath, destinationPrefix, options); } /** * Moves a file from its current location to a new destination prefix. * This operation copies the file and then deletes the original. * If the copy succeeds but the delete fails, the copied file remains. * @param filePath - Path to the file in the bucket to move. * @param destinationPrefix - The new prefix/location where the file should be moved. * @param options - Optional settings including source bucket name and tracing span settings. * @returns A promise resolving to a MoveReturnType object indicating success, source and destination, and whether original was deleted. */ async moveFile(filePath, destinationPrefix, options) { return await this.services.moveFile(filePath, destinationPrefix, options); } /** * Renames a file within the same directory by copying it to a new filename and deleting the original. * @param filePath - Path to the file in the bucket to rename. * @param newFilename - The new filename to use. * @param options - Optional tracing span settings. * @returns A promise resolving to a RenameReturnType object indicating success, old and new path, and whether original was deleted. */ async renameFile(filePath, newFilename, options) { return await this.services.renameFile(filePath, newFilename, options); } /** * Deletes a file from the S3 bucket. Handles missing files gracefully. * @param filePath - Path to the file in the bucket to delete. * @param options - Optional tracing span settings. * @returns A promise resolving to a DeleteReturnType object indicating success, deletion status, and file path. */ async deleteFile(filePath, options) { if (options) { delete options.bucketName; } return await this.services.deleteFile(filePath, options); } /** * Deletes all objects under the given prefix (folder) in the S3 bucket. * * @param prefix - The S3 key prefix representing the folder to delete. * @param options - Optional settings including tracing span options. * @returns A promise resolving to a DeleteFolderReturnType object containing: * - success: boolean indicating if the folder deletion succeeded. * - failed: number of objects that failed to delete. * - succeeded: number of objects successfully deleted. * - fileDeletionErrors: array of error details for any failed deletions. */ async deleteFolder(prefix, options) { return await this.services.deleteFolder(prefix, options); } /** ╔════════════════════════════════════════════════════════════════════════════════╗ ║ 📤 UPLOAD MANAGER ║ ║ Handles file uploads to S3, including direct uploads, multipart uploads, and ║ ║ retry logic for reliability. ║ ╚════════════════════════════════════════════════════════════════════════════════╝ */ /** * Uploads a file to the configured S3 bucket. * Automatically chooses between single and multipart upload based on size. * @param file - Object containing file name, content (Buffer or Readable), optional MIME type, and optional size hint. * @param options - Optional settings including prefix and spanOptions. * @returns A promise that resolves when the file is successfully uploaded. */ async uploadFile(file, options) { return await this.uploads.uploadFile(file, options); } /** * Uploads multiple files concurrently to S3. * Gracefully logs and skips failed uploads without halting the entire batch. * @param files - Array of file objects, each containing file name, content (Buffer or Readable), optional MIME type, and optional size hint. * @param options - Optional settings including prefix and spanOptions. * @returns A promise resolving to a list of files that failed to upload. */ async uploadMultipleFiles(files, options) { return await this.uploads.uploadMultipleFiles(files, options); } /** * Uploads a single file from a local disk path to the S3 bucket. * Automatically determines file name and stream type. * @param localFilePath - Absolute or relative path to the local file to upload. * @param options - Optional settings including prefix and spanOptions. * @returns A promise resolving to the S3 key (path) of the uploaded file. */ async uploadFromDisk(localFilePath, options = {}) { return await this.uploads.uploadFromDisk(localFilePath, options); } /** * Uploads multiple local files to S3 in parallel. * Gracefully logs and skips failed uploads without halting the entire batch. * Automatically determines file names and stream types for each file. * @param localFilePaths - Array of absolute or relative paths to local files. * @param options - Optional settings including prefix and spanOptions. * @returns A promise resolving to an object containing an array of failed file paths. */ async uploadMultipleFromDisk(localFilePaths, options = {}) { return await this.uploads.uploadMultipleFromDisk(localFilePaths, options); } /** ╔════════════════════════════════════════════════════════════════════════════════╗ ║ 📥 DOWNLOAD MANAGER ║ ║ Manages downloads from S3, supporting buffered and streamed file retrieval, ║ ║ with support for metadata extraction and type detection. ║ ╚════════════════════════════════════════════════════════════════════════════════╝ */ /** * Streams a file from the S3 bucket using a readable stream. * @param filePath - Path to the file in the bucket. * @param options - Optional settings including custom timeout duration and tracing options. * @returns A readable stream of the file's contents. */ async getStream(filePath, options) { return await this.downloads.getStream(filePath, options); } /** * Loads a file's contents into memory as a string, Buffer, or parsed object depending on type. * @param filePath - Path to the file in the bucket. * @param options - Optional tracing span settings. * @returns The file's contents as a string, object, or Buffer. */ async downloadFile(filePath, options) { return await this.downloads.downloadFile(filePath, options); } /** * Downloads a file from S3 and saves it to a specified location on disk. * Determines file name and extension based on S3 metadata or user overrides. * @param filePath - Path to the file in the bucket. * @param outDir - Path to folder in which to save the file. * @param options - Optional output filename override and tracing span settings. * @returns A promise that resolves when the file is successfully uploaded. */ async downloadToDisk(filePath, outDir, options) { return await this.downloads.downloadToDisk(filePath, outDir, options); } /** * Downloads all files in the S3 bucket with the specified prefix to a local directory. * * @param prefix - The S3 key prefix to filter which files to download. * @param outDir - The local directory path where files will be saved. * @param options - Optional settings, including tracing span options. * @returns A promise that resolves to a DownloadFolderReturnType object containing: * - success: boolean indicating if all required downloads succeeded (true if at least some files downloaded without all failing). * - message: descriptive status message. * - downloadedFiles: number of files successfully downloaded. * - failedToDownload: array of file paths that failed to download. */ async downloadFolderToDisk(prefix, outDir, options) { return await this.downloads.downloadFolderToDisk(prefix, outDir, options); } /** * Generates a presigned URL for temporary access to a file in S3. * * @param filePath - The S3 key (path) of the file for which to generate a link. * @param options - Optional settings including expiresInSec (expiration time in seconds) and tracing span options. * @returns A promise that resolves to a string containing the presigned URL. */ async getTemporaryDownloadUrl(filePath, options) { return await this.downloads.getTemporaryDownloadUrl(filePath, options); } }