/**
 * Storage abstraction for S3/GCS
 */
import { S3Client, PutObjectCommand, GetObjectCommand, DeleteObjectCommand, HeadObjectCommand, } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
export class StorageClient {
    config;
    s3Client;
    bucket;
    constructor(config) {
        this.config = config;
        this.bucket = config.bucket;
        this.s3Client = new S3Client({
            region: config.region || 'us-east-1',
            credentials: config.accessKeyId && config.secretAccessKey
                ? {
                    accessKeyId: config.accessKeyId,
                    secretAccessKey: config.secretAccessKey,
                }
                : undefined,
        });
    }
    async upload(object) {
        const command = new PutObjectCommand({
            Bucket: this.bucket,
            Key: object.key,
            Body: typeof object.content === 'string' ? Buffer.from(object.content) : object.content,
            ContentType: object.contentType,
            Metadata: object.metadata,
        });
        await this.s3Client.send(command);
        return object.key;
    }
    async download(key) {
        const command = new GetObjectCommand({
            Bucket: this.bucket,
            Key: key,
        });
        const response = await this.s3Client.send(command);
        if (!response.Body) {
            throw new Error(`Object ${key} not found or empty`);
        }
        const chunks = [];
        if (response.Body) {
            const body = response.Body;
            for await (const chunk of body) {
                chunks.push(chunk);
            }
        }
        return Buffer.concat(chunks);
    }
    async delete(key) {
        const command = new DeleteObjectCommand({
            Bucket: this.bucket,
            Key: key,
        });
        await this.s3Client.send(command);
    }
    async getPresignedUrl(key, expiresIn) {
        const command = new GetObjectCommand({
            Bucket: this.bucket,
            Key: key,
        });
        return getSignedUrl(this.s3Client, command, { expiresIn });
    }
    async objectExists(key) {
        try {
            const command = new HeadObjectCommand({
                Bucket: this.bucket,
                Key: key,
            });
            await this.s3Client.send(command);
            return true;
        }
        catch (error) {
            if (error && typeof error === 'object' && 'name' in error && error.name === 'NotFound') {
                return false;
            }
            throw error;
        }
    }
}
//# sourceMappingURL=storage.js.map