"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var S3Provider_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.S3Provider = void 0; const common_1 = require("@nestjs/common"); const config_1 = require("@nestjs/config"); const client_s3_1 = require("@aws-sdk/client-s3"); const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner"); let S3Provider = S3Provider_1 = class S3Provider { constructor(configService) { this.configService = configService; this.logger = new common_1.Logger(S3Provider_1.name); this.configured = false; } onModuleInit() { const storageProvider = this.configService.get('STORAGE_PROVIDER', 's3'); const bucket = this.configService.get('STORAGE_BUCKET'); const region = this.configService.get('AWS_REGION', 'us-east-1'); const accessKeyId = this.configService.get('AWS_ACCESS_KEY_ID'); const secretAccessKey = this.configService.get('AWS_SECRET_ACCESS_KEY'); const endpoint = this.configService.get('STORAGE_ENDPOINT'); if (!bucket || !accessKeyId || !secretAccessKey) { this.logger.warn('Storage not configured - missing STORAGE_BUCKET or AWS credentials'); return; } this.bucket = bucket; this.provider = storageProvider; const config = { region, credentials: { accessKeyId, secretAccessKey, }, }; if (endpoint) { config.endpoint = endpoint; config.forcePathStyle = true; } this.client = new client_s3_1.S3Client(config); this.configured = true; this.logger.log(`Storage configured: ${storageProvider} - ${bucket}`); } isConfigured() { return this.configured; } getBucket() { return this.bucket; } getProvider() { return this.provider; } async getUploadUrl(options) { if (!this.configured) { throw new Error('Storage not configured'); } const expiresIn = options.expiresIn || 900; const command = new client_s3_1.PutObjectCommand({ Bucket: options.bucket || this.bucket, Key: options.key, ContentType: options.contentType, ContentLength: options.contentLength, Metadata: options.metadata, }); const url = await (0, s3_request_presigner_1.getSignedUrl)(this.client, command, { expiresIn }); const expiresAt = new Date(Date.now() + expiresIn * 1000); return { url, expiresAt }; } async getDownloadUrl(key, expiresIn = 3600) { if (!this.configured) { throw new Error('Storage not configured'); } const command = new client_s3_1.GetObjectCommand({ Bucket: this.bucket, Key: key, }); const url = await (0, s3_request_presigner_1.getSignedUrl)(this.client, command, { expiresIn }); const expiresAt = new Date(Date.now() + expiresIn * 1000); return { url, expiresAt }; } async deleteObject(key) { if (!this.configured) { throw new Error('Storage not configured'); } const command = new client_s3_1.DeleteObjectCommand({ Bucket: this.bucket, Key: key, }); await this.client.send(command); } async headObject(key) { if (!this.configured) { throw new Error('Storage not configured'); } try { const command = new client_s3_1.HeadObjectCommand({ Bucket: this.bucket, Key: key, }); const response = await this.client.send(command); return { contentLength: response.ContentLength || 0, contentType: response.ContentType || 'application/octet-stream', }; } catch (error) { if (error.name === 'NotFound') { return null; } throw error; } } generatePath(tenantId, folder, uploadId, filename) { const sanitized = filename.replace(/[^a-zA-Z0-9.-]/g, '_'); return `${tenantId}/${folder}/${uploadId}/${sanitized}`; } }; exports.S3Provider = S3Provider; exports.S3Provider = S3Provider = S3Provider_1 = __decorate([ (0, common_1.Injectable)(), __metadata("design:paramtypes", [config_1.ConfigService]) ], S3Provider); //# sourceMappingURL=s3.provider.js.map