/
aaronair
/
Test_task_rt_solution
Обзор
Документация
Войти
/
aaronair
/
Test_task_rt_solution
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
backend/src/plugins/s3.ts
105 строк
3 KB
Ilikedrinkpivo
first_commit
28 май 2026, 14:51
28 май 2026, 14:51
b4498fc
Код
Авторство
О чём код?
import { CreateBucketCommand, DeleteObjectCommand, GetObjectCommand, HeadBucketCommand, PutBucketCorsCommand, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; import type { Env } from "../config.js"; function createS3Client(env: Env, endpoint: string) { return new S3Client({ region: env.S3_REGION, endpoint, forcePathStyle: true, credentials: { accessKeyId: env.S3_ACCESS_KEY, secretAccessKey: env.S3_SECRET_KEY, }, }); } export class S3Service { private client: S3Client; private presignClient: S3Client; private bucket: string; private corsOrigin: string; constructor(env: Env) { this.bucket = env.S3_BUCKET; this.corsOrigin = env.CORS_ORIGIN; this.client = createS3Client(env, env.S3_ENDPOINT); const publicEndpoint = env.S3_PUBLIC_ENDPOINT ?? env.S3_ENDPOINT; this.presignClient = publicEndpoint === env.S3_ENDPOINT ? this.client : createS3Client(env, publicEndpoint); } 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 PutBucketCorsCommand({ Bucket: this.bucket, CORSConfiguration: { CORSRules: [ { AllowedHeaders: ["*"], AllowedMethods: ["GET", "PUT", "HEAD"], AllowedOrigins: [this.corsOrigin], ExposeHeaders: ["ETag"], MaxAgeSeconds: 3600, }, ], }, }), ); } catch { // MinIO may not support PutBucketCors via S3 API; CORS can be set via mc admin. } } async presignUpload(key: string, contentType: string) { const command = new PutObjectCommand({ Bucket: this.bucket, Key: key, ContentType: contentType, }); return getSignedUrl(this.presignClient, command, { expiresIn: 3600 }); } async presignDownload(key: string) { return getSignedUrl( this.presignClient, new GetObjectCommand({ Bucket: this.bucket, Key: key }), { expiresIn: 3600 }, ); } async deleteObject(key: string) { await this.client.send( new DeleteObjectCommand({ Bucket: this.bucket, Key: key }), ); } } export async function registerS3(app: import("fastify").FastifyInstance, env: Env) { const s3 = new S3Service(env); await s3.ensureBucket(); app.decorate("s3", s3); } declare module "fastify" { interface FastifyInstance { s3: S3Service; } }