oak-general-business/lib/utils/cos/s3.js

102 lines
3.8 KiB
JavaScript

"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, presignMultiPartUpload, getPercent, parallelism, retryTimes, retryDelay, onChunkSuccess } = options;
const uploadMeta = extraFile.uploadMeta;
if (extraFile.enableChunkedUpload) {
return (0, common_1.chunkUpload)({
extraFile,
presignMultiPartUpload: presignMultiPartUpload,
uploadFn,
file,
getPercent,
parallelism: parallelism,
retryTimes: retryTimes,
retryDelay: retryDelay,
onChunkSuccess: onChunkSuccess,
});
}
else {
let response;
try {
// S3 使用预签名 URL 直接上传,不需要额外的 formData
response = await uploadFn({
file,
name: 'file',
uploadUrl: uploadMeta.uploadUrl,
formData: {},
autoInform: true,
getPercent,
uploadId: extraFile.id,
method: "PUT",
isFilePath: true,
});
}
catch (err) {
throw new Exception_2.OakNetworkException('网络异常,请求失败');
}
let isSuccess = false;
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;