web-service/apps/assets/src/services/s3.service.ts

79 lines
2.2 KiB
TypeScript

import { Injectable, OnModuleInit } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import {
DeleteObjectCommand,
PutObjectCommand,
S3Client,
} from '@aws-sdk/client-s3';
import { BadRequestRpcException } from '@freeblox/shared';
import { HttpRequest } from '@aws-sdk/protocol-http';
import { S3RequestPresigner } from '@aws-sdk/s3-request-presigner';
import { parseUrl } from '@aws-sdk/url-parser';
import { formatUrl } from '@aws-sdk/util-format-url';
import { Hash } from '@aws-sdk/hash-node';
import { fromEnv } from '@aws-sdk/credential-providers';
@Injectable()
export class S3Service implements OnModuleInit {
private s3: S3Client;
private presigner: S3RequestPresigner;
constructor(private config: ConfigService) {}
onModuleInit() {
const s3Config = this.config.get('s3');
this.s3 = new S3Client({
...s3Config,
});
this.presigner = new S3RequestPresigner({
credentials: fromEnv(),
region: s3Config.region,
sha256: Hash.bind(null, 'sha256'),
});
}
async uploadFile(key: string, data: Buffer, bucket?: string) {
try {
const command = new PutObjectCommand({
Key: key,
Bucket: bucket || this.config.get('s3.bucket'),
Body: data,
});
await this.s3.send(command);
} catch (error) {
throw new BadRequestRpcException(`Upload failed: ${error.message}`);
}
}
async getFileUrl(key: string, bucket?: string) {
const s3Config = this.config.get('s3');
bucket = bucket || s3Config.bucket;
let url: ReturnType<typeof parseUrl>;
if (s3Config.endpoint) {
url = parseUrl(`${s3Config.endpoint}/${bucket}/${key}`);
} else {
url = parseUrl(
`https://${bucket}.s3${
s3Config.region ? '-' + s3Config.region : ''
}.amazonaws.com/${key}`,
);
}
const signedUrlObject = await this.presigner.presign(new HttpRequest(url));
return formatUrl(signedUrlObject);
}
async deleteFile(key: string, bucket?: string) {
try {
const command = new DeleteObjectCommand({
Key: key,
Bucket: bucket || this.config.get('s3.bucket'),
});
await this.s3.send(command);
} catch {
throw new BadRequestRpcException('Delete failed');
}
}
}