import { CreateBucketCommand, DeleteObjectCommand, HeadBucketCommand, PutBucketPolicyCommand, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3"; import sharp from "sharp"; import { env } from "../config/env.js"; export class S3Storage { client = new S3Client({ endpoint: env.S3_ENDPOINT, region: env.S3_REGION, forcePathStyle: env.S3_FORCE_PATH_STYLE, credentials: { accessKeyId: env.S3_ACCESS_KEY, secretAccessKey: env.S3_SECRET_KEY }, }); bucket = env.S3_BUCKET; publicUrl(key) { return `${env.MEDIA_PUBLIC_URL}/${key}`; } async put(key, body, contentType) { await this.client.send(new PutObjectCommand({ Bucket: this.bucket, Key: key, Body: body, ContentType: contentType, CacheControl: "public, max-age=31536000, immutable", })); } async remove(key) { await this.client.send(new DeleteObjectCommand({ Bucket: this.bucket, Key: key })); } async ensureBucket() { try { await this.client.send(new HeadBucketCommand({ Bucket: this.bucket })); } catch { await this.client.send(new CreateBucketCommand({ Bucket: this.bucket })); } try { await this.client.send(new PutBucketPolicyCommand({ Bucket: this.bucket, Policy: JSON.stringify({ Version: "2012-10-17", Statement: [ { Effect: "Allow", Principal: { AWS: ["*"] }, Action: ["s3:GetObject"], Resource: [`arn:aws:s3:::${this.bucket}/*`], }, ], }), })); } catch { } } } export const ACCEPTED_IMAGE_TYPES = [ "image/jpeg", "image/png", "image/webp", "image/avif", "image/gif", ]; export async function toWebp(input) { const { data, info } = await sharp(input) .rotate() .resize({ width: 2000, height: 2000, fit: "inside", withoutEnlargement: true }) .webp({ quality: 82 }) .toBuffer({ resolveWithObject: true }); return { data, width: info.width, height: info.height, size: info.size }; } //# sourceMappingURL=s3-storage.js.map