"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const assert_1 = require("oak-domain/lib/utils/assert"); const Exception_1 = require("../../types/Exception"); const Exception_2 = require("oak-domain/lib/types/Exception"); const common_1 = require("./common"); class S3 { name = 's3'; autoInform() { return false; } getConfig(application) { const { system } = application; const { config } = system; const s3Config = config.Cos?.s3; (0, assert_1.assert)(s3Config); const { accessKey, endpoint, defaultBucket } = s3Config; const account = config.Account?.s3?.find((ele) => ele.accessKey === accessKey); (0, assert_1.assert)(account); return { config: s3Config, account, endpoint, defaultBucket, }; } formKey(extraFile) { const { id, extension, objectId } = extraFile; (0, assert_1.assert)(objectId); return `extraFile/${objectId}${extension ? '.' + extension : ''}`; } async upload(options) { const { extraFile, uploadFn, file, getPercent, parallelism, retryTimes, retryDelay, onChunkSuccess } = options; const uploadMeta = extraFile.uploadMeta; if (extraFile.enableChunkedUpload) { return (0, common_1.chunkUpload)({ extraFile, uploadFn, file, getPercent, parallelism: parallelism, retryTimes: retryTimes, retryDelay: retryDelay, onChunkSuccess: onChunkSuccess, }); } else { let response; try { // S3 使用预签名 URL 直接上传,不需要额外的 formData response = await uploadFn(file, 'file', uploadMeta.uploadUrl, {}, true, getPercent, extraFile.id, "PUT"); } catch (err) { throw new Exception_2.OakNetworkException('网络异常,请求失败'); } let isSuccess = false; if (process.env.OAK_PLATFORM === 'wechatMp') { // 小程序端上传 if (response.errMsg === 'uploadFile:ok') { const statusCode = response.statusCode; isSuccess = statusCode === 200 || statusCode === 204; } } else { isSuccess = response.status === 200 || response.status === 204; } if (isSuccess) { return; } } throw new Exception_1.OakUploadException('文件上传S3失败'); } composeFileUrl(options) { const { application, extraFile, style } = options; const { config: s3CosConfig, endpoint } = this.getConfig(application); if (s3CosConfig) { let bucket = s3CosConfig.buckets.find((ele) => ele.name === extraFile.bucket); if (bucket) { const { domain, protocol, pathStyle } = bucket; let protocol2 = protocol; if (protocol instanceof Array) { const index = protocol.includes('https:') ? protocol.findIndex((ele) => ele === 'https:') : 0; protocol2 = protocol[index]; } const key = this.formKey(extraFile); // 如果使用 pathStyle (Minio 常用) if (pathStyle && endpoint) { return `${protocol2}//${domain}/${bucket.name}/${key}${style ? style : ''}`; } // 否则使用虚拟主机风格 (AWS S3 默认) return `${protocol2}//${domain}/${key}${style ? style : ''}`; } } return ''; } } exports.default = S3;