UNPKG

@d3oxy/s3-pilot

Version:

A TypeScript wrapper for AWS S3 and S3-compatible services (R2, MinIO, DigitalOcean Spaces) with a simplified single-client, single-bucket architecture.

270 lines (269 loc) 11 kB
import type { Readable } from "node:stream"; import { type S3ClientConfigType as AWSConfigType, PutObjectCommand } from "@aws-sdk/client-s3"; /** * Configuration for S3Pilot instance. * Each instance represents a single S3 client connected to a single bucket. */ export interface S3PilotConfig { region: string; accessKeyId: string; secretAccessKey: string; bucket: string; keyPrefix?: string; additionalConfig?: AWSConfigType; validateBucketOnInit?: boolean; /** * Custom S3-compatible endpoint URL. * Use this for S3-compatible services like Cloudflare R2, DigitalOcean Spaces, MinIO, etc. * Example: "https://ACCOUNT_ID.r2.cloudflarestorage.com" */ endpoint?: string; /** * Base URL for generating public URLs. * Use this when your files are served from a custom domain, CDN, or R2 public bucket. * Example: "https://assets.example.com" or "https://pub-xxx.r2.dev" */ publicBaseUrl?: string; } export interface UploadFileResponse { url: string; key: string; } export interface UploadFileStreamResponse extends UploadFileResponse { etag?: string; versionId?: string; } export interface GetFileResponse { buffer: Buffer; contentType?: string; contentLength?: number; etag?: string; lastModified?: Date; } export interface GetFileStreamResponse { stream: Readable; contentType?: string; contentLength?: number; etag?: string; lastModified?: Date; } export interface DeleteFilesResponse { deleted: string[]; errors: Array<{ key: string; code?: string; message?: string; }>; } /** * S3Pilot class abstracts interactions with AWS S3 SDK to provide a cleaner API. * Each instance represents a single S3 client connected to a single bucket. * * Supports S3-compatible services like Cloudflare R2, DigitalOcean Spaces, MinIO, etc. * via the `endpoint` configuration option. */ export declare class S3Pilot { private readonly s3; private readonly bucket; private readonly region; private readonly keyPrefix?; private readonly endpoint?; private readonly publicBaseUrl?; /** * Creates an instance of the S3Pilot class. * @param config - The configuration object for the S3 client and bucket. */ constructor(config: S3PilotConfig); /** * Validates the bucket on initialization. * Called from constructor if validateBucketOnInit is true. * Note: This method is used conditionally in the constructor, which may trigger unused member warnings. * * @throws An error if the bucket is not valid or the user does not have access to it. */ private validateBucketOnInit; /** * Retrieves the URL for a given object key. * * URL generation priority: * 1. If `publicBaseUrl` is configured: `{publicBaseUrl}/{key}` * 2. If `endpoint` is configured (S3-compatible): `{endpoint}/{bucket}/{key}` * 3. Default AWS S3 format: `https://{bucket}.s3.{region}.amazonaws.com/{key}` * * @param key - The object key. * @returns The URL of the object. */ getUrl(key: string): string; /** * Uploads a file stream to the bucket. * * @param params - The parameters for the file upload. * @param params.filename - The name of the file. * @param params.folder - The folder to upload the file to (optional). * @param params.stream - The readable stream to upload. * @param params.contentType - The content type of the file. * @param params.contentLength - The content length of the stream (optional, but recommended for large files). * @param params.additionalParams - Additional parameters for the PutObjectCommand (optional). * @returns A promise that resolves to an object containing the URL, key, etag, and versionId of the uploaded file. * @throws {Error} If the file fails to upload. */ uploadFileStream(params: { filename: string; folder?: string; stream: Readable; contentType: string; contentLength?: number; additionalParams?: Omit<PutObjectCommand, "Bucket" | "Key" | "Body">; }): Promise<UploadFileStreamResponse>; /** * Uploads a file to the bucket. * * @param params - The parameters for the file upload. * @param params.filename - The name of the file. * @param params.folder - The folder to upload the file to (optional). * @param params.file - The file to upload. * @param params.contentType - The content type of the file. * @param params.additionalParams - Additional parameters for the PutObjectCommand (optional). * @returns A promise that resolves to an object containing the URL and key of the uploaded file. * @throws {Error} If the file fails to upload. */ uploadFile(params: { filename: string; folder?: string; file: Buffer | Uint8Array | Blob | string; contentType: string; additionalParams?: Omit<PutObjectCommand, "Bucket" | "Key" | "Body">; }): Promise<UploadFileResponse>; /** * Deletes a file from the bucket. * * @param params - The parameters for deleting the file. * @param params.key - The key of the file to delete. * @returns A Promise that resolves when the file is successfully deleted. */ deleteFile(params: { key: string; }): Promise<void>; /** * Deletes multiple files from the bucket in a single request. * Automatically batches requests if more than 1000 keys are provided (S3 API limit). * * @param params - The parameters for deleting files. * @param params.keys - Array of keys to delete. * @returns A promise that resolves to an object containing deleted keys and any errors. */ deleteFiles(params: { keys: string[]; }): Promise<DeleteFilesResponse>; /** * Renames a file in the bucket. * * @param params - The parameters for renaming the file. * @param params.oldKey - The key of the file to be renamed. * @param params.newFolder - The new folder for the renamed file (optional). * @param params.newFilename - The new filename for the renamed file (optional). * @returns A promise that resolves to an object containing the URL and key of the renamed file. * @deprecated This function is not stable and should not be used. */ renameFile(params: { oldKey: string; newFolder?: string; newFilename?: string; }): Promise<{ url: string; key: string; }>; /** * Moves a file within the bucket from one key to another. * Uses S3's CopyObject + DeleteObject operations. * * @param params - The parameters for moving the file. * @param params.sourceKey - The current key of the file to move. * @param params.destinationKey - The new key for the file. * @returns A promise that resolves to an object containing the URL and key of the moved file. * @throws {Error} If the file cannot be moved. */ moveFile(params: { sourceKey: string; destinationKey: string; }): Promise<UploadFileResponse>; /** * Moves a file from this bucket to another bucket. * First attempts a direct S3 copy (works if same AWS credentials have access to both buckets). * Falls back to download + upload if direct copy fails (for cross-account moves). * * @param params - The parameters for moving the file. * @param params.sourceKey - The key of the file to move from this bucket. * @param params.destinationKey - The key for the file in the destination bucket. * @param params.destination - The destination S3Pilot instance. * @returns A promise that resolves to an object containing the URL and key of the moved file. * @throws {Error} If the file cannot be moved. */ moveToBucket(params: { sourceKey: string; destinationKey: string; destination: S3Pilot; }): Promise<UploadFileResponse>; /** * Downloads a file from S3 and returns its content as a Buffer. * This method is useful for server-side file processing or when you need to * stream file content to clients through your API server. * * @param params - The parameters for downloading the file. * @param params.key - The key of the file to download. * @returns A promise that resolves to an object containing the file buffer and metadata. * @throws {Error} If the file cannot be downloaded or doesn't exist. */ getFile(params: { key: string; }): Promise<GetFileResponse>; /** * Downloads a file from S3 and returns its content as a readable stream. * This method is useful for streaming large files efficiently without loading * the entire file into memory. * * @param params - The parameters for downloading the file. * @param params.key - The key of the file to download. * @returns A promise that resolves to an object containing the file stream and metadata. * @throws {Error} If the file cannot be downloaded or doesn't exist. */ getFileStream(params: { key: string; }): Promise<GetFileStreamResponse>; /** * Generates a signed URL for accessing an object in the bucket. * Enhanced version with support for download-specific headers to force browser download * and avoid CORS issues. * * @param params - Additional parameters for generating the signed URL. * @param params.key - The key of the object. * @param params.expiresIn - The expiration time of the signed URL in seconds. Defaults to 1 hour (3600 seconds). * @param params.responseContentDisposition - Optional content disposition header to force download behavior. * @param params.responseContentType - Optional content type header. * @param params.responseCacheControl - Optional cache control header. * @param params.responseContentLanguage - Optional content language header. * @param params.responseContentEncoding - Optional content encoding header. * @param params.responseExpires - Optional expires header. * @returns A promise that resolves to the signed URL. */ generateSignedUrl(params: { key: string; expiresIn?: number; responseContentDisposition?: string; responseContentType?: string; responseCacheControl?: string; responseContentLanguage?: string; responseContentEncoding?: string; responseExpires?: Date; }): Promise<string>; /** * Deletes a folder and all its contents from the bucket. * * @param params - The parameters for deleting the folder. * @param params.folder - The folder to delete. * @returns A promise that resolves when the folder and its contents are successfully deleted. */ deleteFolder(params: { folder: string; }): Promise<void>; }