81 lines
2.1 KiB
TypeScript
81 lines
2.1 KiB
TypeScript
import { S3Client, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';
|
|
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
|
|
// Initialize S3 client
|
|
const s3Client = new S3Client({
|
|
region: process.env.AWS_REGION || 'ir-thr-at1',
|
|
endpoint: process.env.AWS_S3_ENDPOINT,
|
|
credentials: {
|
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID || '',
|
|
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || '',
|
|
},
|
|
});
|
|
|
|
const BUCKET_NAME = process.env.AWS_S3_BUCKET || '';
|
|
|
|
export interface UploadFileParams {
|
|
file: File;
|
|
key: string;
|
|
contentType?: string;
|
|
}
|
|
|
|
/**
|
|
* Upload a file to S3
|
|
*/
|
|
export async function uploadFileToS3(params: UploadFileParams): Promise<string> {
|
|
const { file, key, contentType } = params;
|
|
|
|
// Convert File to Buffer
|
|
const arrayBuffer = await file.arrayBuffer();
|
|
const buffer = Buffer.from(arrayBuffer);
|
|
|
|
const command = new PutObjectCommand({
|
|
Bucket: BUCKET_NAME,
|
|
Key: key,
|
|
Body: buffer,
|
|
ACL: "public-read",
|
|
ContentType: contentType || file.type,
|
|
});
|
|
|
|
await s3Client.send(command);
|
|
|
|
// Return the public URL
|
|
return `https://${BUCKET_NAME}.s3.ir-thr-at1.arvanstorage.ir/${key}`;
|
|
}
|
|
|
|
/**
|
|
* Delete a file from S3
|
|
*/
|
|
export async function deleteFileFromS3(key: string): Promise<void> {
|
|
const command = new DeleteObjectCommand({
|
|
Bucket: BUCKET_NAME,
|
|
Key: key,
|
|
});
|
|
|
|
await s3Client.send(command);
|
|
}
|
|
|
|
/**
|
|
* Generate a presigned URL for uploading
|
|
*/
|
|
export async function getPresignedUploadUrl(key: string, contentType: string): Promise<string> {
|
|
const command = new PutObjectCommand({
|
|
Bucket: BUCKET_NAME,
|
|
Key: key,
|
|
ContentType: contentType,
|
|
});
|
|
|
|
const url = await getSignedUrl(s3Client, command, { expiresIn: 3600 }); // 1 hour
|
|
return url;
|
|
}
|
|
|
|
/**
|
|
* Generate a unique key for file uploads
|
|
*/
|
|
export function generateFileKey(folder: string, filename: string): string {
|
|
const timestamp = Date.now();
|
|
const randomString = Math.random().toString(36).substring(2, 15);
|
|
const sanitizedFilename = filename.replace(/[^a-zA-Z0-9.-]/g, '_');
|
|
return `${folder}/${timestamp}-${randomString}-${sanitizedFilename}`;
|
|
}
|