@d3oxy/s3-pilot
Version:
A TypeScript wrapper for AWS S3 with support for multiple clients, buckets, and secure file downloads.
280 lines (279 loc) • 13.6 kB
TypeScript
import { S3ClientConfigType as AWSConfigType, PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { Readable } from "stream";
/**
* Type for configuring an individual S3 client.
* @template BucketNames - Bucket names for the client.
*/
export type S3ClientSettings<BucketNames extends string> = {
region: string;
accessKeyId: string;
secretAccessKey: string;
buckets: BucketNames[];
keyPrefix?: string;
additionalConfig?: AWSConfigType;
enableDefaultAllowedExtensions?: boolean;
allowedExtensions?: string[];
validateBucketOnInit?: boolean;
};
/**
* Type for setting up multiple S3 clients.
* @template Clients - Record of client names to their configurations.
*/
export type S3ClientsSetup<Clients extends Record<string, S3ClientSettings<string>>> = Clients;
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;
}
/**
* S3Pilot class abstracts interactions with AWS S3 SDK to provide a cleaner API.
* @template Clients - Mapping of client names to their configurations.
*/
export declare class S3Pilot<Clients extends Record<string, S3ClientSettings<string>>> {
/**
* Represents the client instances for different clients.
*/
private clientInstances;
/**
* Creates an instance of the S3Pilot class.
* @param config - The configuration object for setting up S3 clients.
*/
constructor(config: S3ClientsSetup<Clients>);
/**
* Retrieves the URL for a given object key in a specific bucket of a client.
* @param clientName - The name of the client.
* @param bucket - The bucket object from the client.
* @param key - The object key.
* @returns A promise that resolves to the URL of the object.
*/
getUrl<ClientName extends keyof Clients>(clientName: ClientName, bucket: Clients[ClientName]["buckets"][number], key: string): Promise<string>;
/**
* Validates the specified bucket on initialization.
*
* @param client - The S3 client.
* @param bucket - The name of the bucket to validate.
* @throws An error if the bucket is not valid or the user does not have access to it.
*/
private validateBucketOnInit;
/**
* Validates if a bucket is available for a given client.
*
* @template ClientName - The name of the client.
* @param clientName - The name of the client.
* @param bucket - The bucket to validate.
* @throws {Error} If the bucket is not available for the client.
*/
private validateBucket;
private validateExtension;
/**
* Retrieves the client instance for the specified client name.
*
* @template ClientName - The type of the client name.
* @param {ClientName} clientName - The name of the client.
* @returns {Object} - An object containing the S3 client, a set of buckets, and an optional key prefix.
*/
getClient<ClientName extends keyof Clients>(clientName: ClientName): {
s3: S3Client;
buckets: Set<string>;
keyPrefix?: string;
region: string;
enableDefaultAllowedExtensions?: boolean;
allowedExtensions?: string[];
};
/**
* Uploads a file stream to the specified bucket for the given client.
*
* @template ClientName - The name of the client.
* @param {ClientName} clientName - The name of the client.
* @param {Clients[ClientName]["buckets"][number]} bucket - The bucket to upload the file to.
* @param {Object} params - The parameters for the file upload.
* @param {string} params.filename - The name of the file.
* @param {string} [params.folder] - The folder to upload the file to (optional).
* @param {Readable} params.stream - The readable stream to upload.
* @param {string} params.contentType - The content type of the file.
* @param {number} [params.contentLength] - The content length of the stream (optional, but recommended for large files).
* @param {Omit<PutObjectCommand, "Bucket" | "Key" | "Body">} [params.additionalParams] - Additional parameters for the PutObjectCommand (optional).
* @returns {Promise<UploadFileStreamResponse>} A promise that resolves to an object containing the URL, key, etag, and versionId of the uploaded file.
* @throws {Error} If the file extension is invalid or if the file fails to upload.
*/
uploadFileStream<ClientName extends keyof Clients>(clientName: ClientName, bucket: Clients[ClientName]["buckets"][number], params: {
filename: string;
folder?: string;
stream: Readable;
contentType: string;
contentLength?: number;
additionalParams?: Omit<PutObjectCommand, "Bucket" | "Key" | "Body">;
}): Promise<UploadFileStreamResponse>;
/**
* Uploads a file to the specified bucket for the given client.
*
* @template ClientName - The name of the client.
* @param {ClientName} clientName - The name of the client.
* @param {Clients[ClientName]["buckets"][number]} bucket - The bucket to upload the file to.
* @param {Object} params - The parameters for the file upload.
* @param {string} params.filename - The name of the file.
* @param {string} [params.folder] - The folder to upload the file to (optional).
* @param {Buffer | Uint8Array | Blob | string} params.file - The file to upload.
* @param {string} params.contentType - The content type of the file.
* @param {Omit<PutObjectCommand, "Bucket" | "Key" | "Body">} [params.additionalParams] - Additional parameters for the PutObjectCommand (optional).
* @returns {Promise<UploadFileResponse>} A promise that resolves to an object containing the URL and key of the uploaded file.
* @throws {Error} If the file extension is invalid or if the file fails to upload.
*/
uploadFile<ClientName extends keyof Clients>(clientName: ClientName, bucket: Clients[ClientName]["buckets"][number], 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 specified bucket.
*
* @param clientName - The name of the client.
* @param bucket - The bucket from which to delete the file.
* @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<ClientName extends keyof Clients>(clientName: ClientName, bucket: Clients[ClientName]["buckets"][number], params: {
key: string;
}): Promise<void>;
/**
* Renames a file in the specified bucket of a client.
*
* @template ClientName - The name of the client.
* @param {ClientName} clientName - The name of the client.
* @param {Clients[ClientName]["buckets"][number]} bucket - The bucket in which the file is located.
* @param {Object} params - The parameters for renaming the file.
* @param {string} params.oldKey - The key of the file to be renamed.
* @param {string} [params.newFolder] - The new folder for the renamed file (optional).
* @param {string} [params.newFilename] - The new filename for the renamed file (optional).
* @returns {Promise<{
* url: string;
* key: string;
* acl: ObjectCannedACL;
* }>} - A promise that resolves to an object containing the URL, key, and ACL of the renamed file.
* @deprecated This function is not stable and should not be used.
*/
renameFile<ClientName extends keyof Clients>(clientName: ClientName, bucket: Clients[ClientName]["buckets"][number], params: {
oldKey: string;
newFolder?: string;
newFilename?: string;
}): Promise<{
url: string;
key: string;
}>;
/**
* 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.
*
* @template ClientName - The name of the client.
* @param clientName - The name of the client.
* @param bucket - The bucket containing the file.
* @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<ClientName extends keyof Clients>(clientName: ClientName, bucket: Clients[ClientName]["buckets"][number], 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.
*
* @template ClientName - The name of the client.
* @param clientName - The name of the client.
* @param bucket - The bucket containing the file.
* @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<ClientName extends keyof Clients>(clientName: ClientName, bucket: Clients[ClientName]["buckets"][number], params: {
key: string;
}): Promise<GetFileStreamResponse>;
/**
* Generates a signed URL for accessing an object in a specific bucket of a client.
* Enhanced version with support for download-specific headers to force browser download
* and avoid CORS issues.
*
* @param clientName - The name of the client.
* @param bucket - The bucket to generate the signed URL for.
* @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<ClientName extends keyof Clients>(clientName: ClientName, bucket: Clients[ClientName]["buckets"][number], params: {
key: string;
expiresIn?: number;
responseContentDisposition?: string;
responseContentType?: string;
responseCacheControl?: string;
responseContentLanguage?: string;
responseContentEncoding?: string;
responseExpires?: Date;
}): Promise<string>;
/**
* Extracts the key from the given URL.
* @param url - The URL from which to extract the key.
* @returns A Promise that resolves to the extracted key.
* @throws An error if the URL is invalid or the key cannot be extracted.
*/
getKeyFromUrl(url: string): Promise<string>;
/**
* Moves a file from one key to another, possibly across buckets, for the given client.
*
* @template ClientName - The name of the client.
* @param clientName - The name of the client.
* @param sourceBucket - The source bucket.
* @param destinationBucket - The destination bucket.
* @param params - The parameters for moving the file.
* @param params.sourceKey - The 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.
*/
moveFile<ClientName extends keyof Clients>(clientName: ClientName, sourceBucket: Clients[ClientName]["buckets"][number], destinationBucket: Clients[ClientName]["buckets"][number], params: {
sourceKey: string;
destinationKey: string;
}): Promise<UploadFileResponse>;
/**
* Deletes a folder and all its contents from the specified bucket.
*
* @template ClientName - The name of the client.
* @param clientName - The name of the client.
* @param bucket - The bucket from which to delete the folder.
* @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<ClientName extends keyof Clients>(clientName: ClientName, bucket: Clients[ClientName]["buckets"][number], params: {
folder: string;
}): Promise<void>;
}