@cloudbase/storage
Version:
cloudbase js sdk storage module
320 lines (292 loc) • 9.95 kB
text/typescript
import { constants, utils, helpers } from '@cloudbase/utilities';
import { ICloudbase } from '@cloudbase/types';
import { ICloudbaseComponent } from '@cloudbase/types/component';
import {
ICloudbaseFileMetaDataRes,
ICloudbaseFileInfo,
ICloudbaseUploadFileParams,
ICloudbaseUploadFileResult,
ICloudbaseGetUploadMetadataParams,
ICloudbaseDeleteFileParams,
ICloudbaseDeleteFileResult,
ICloudbaseGetTempFileURLResult,
ICloudbaseGetTempFileURLParams,
ICloudbaseDownloadFileResult,
ICloudbaseDownloadFileParams
} from '@cloudbase/types/storage';
declare const cloudbase: ICloudbase;
const { getSdkName, ERRORS, COMMUNITY_SITE_URL } = constants;
const { isArray, isString, isPalinObject, execCallback } = utils;
const { catchErrorsDecorator } = helpers;
const COMPONENT_NAME = 'storage';
class CloudbaseStorage {
@catchErrorsDecorator({
customInfo: {
className: 'Cloudbase',
methodName: 'uploadFile'
},
title: '上传文件失败',
messages: [
'请确认以下各项:',
' 1 - 调用 uploadFile() 的语法或参数是否正确',
' 2 - 当前域名是否在安全域名列表中:https://console.cloud.tencent.com/tcb/env/safety',
' 3 - 云存储安全规则是否限制了当前登录状态访问',
`如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
]
})
public async uploadFile(
params: ICloudbaseUploadFileParams,
callback?: Function
): Promise<ICloudbaseUploadFileResult> {
const { cloudPath, filePath, onUploadProgress } = params;
if (!isString(cloudPath) || !filePath) {
throw new Error(JSON.stringify({
code: ERRORS.INVALID_PARAMS,
msg: `[${COMPONENT_NAME}.uploadFile] invalid params`
}));
}
const action = 'storage.getUploadMetadata';
// @ts-ignore
const request = this.request;
const metaData: ICloudbaseFileMetaDataRes = await request.send(action, {
path: cloudPath
});
const {
data: { url, authorization, token, fileId, cosFileId, download_url },
requestId
} = metaData;
// 使用临时密匙上传文件
// @see https://cloud.tencent.com/document/product/436/14048
const data = {
key: cloudPath,
signature: authorization,
'x-cos-meta-fileid': cosFileId,
'success_action_status': '201',
'x-cos-security-token': token
};
const res = await request.upload({
url,
data,
file: filePath,
name: cloudPath,
onUploadProgress
});
if (res.statusCode === 201) {
return execCallback(callback, null, {
fileID: fileId,
download_url,
requestId
});
} else {
return execCallback(callback, new Error(`[${getSdkName()}][${ERRORS.OPERATION_FAIL}][${COMPONENT_NAME}]:${res.data}`));
}
}
@catchErrorsDecorator({
customInfo: {
className: 'Cloudbase',
methodName: 'getUploadMetadata'
},
title: '获取上传元信息失败',
messages: [
'请确认以下各项:',
' 1 - 调用 getUploadMetadata() 的语法或参数是否正确',
' 2 - 当前域名是否在安全域名列表中:https://console.cloud.tencent.com/tcb/env/safety',
' 3 - 云存储安全规则是否限制了当前登录状态访问',
`如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
]
})
public async getUploadMetadata(
params: ICloudbaseGetUploadMetadataParams,
callback?: Function
): Promise<any> {
const { cloudPath } = params;
if (!isString(cloudPath)) {
throw new Error(JSON.stringify({
code: ERRORS.INVALID_PARAMS,
msg: `[${COMPONENT_NAME}.getUploadMetadata] invalid cloudPath`
}));
}
// @ts-ignore
const request = this.request;
const action = 'storage.getUploadMetadata';
try {
const metaData = await request.send(action, {
path: cloudPath
});
return execCallback(callback, null, metaData);
} catch (err) {
return execCallback(callback, err);
}
}
@catchErrorsDecorator({
customInfo: {
className: 'Cloudbase',
methodName: 'deleteFile'
},
title: '删除文件失败',
messages: [
'请确认以下各项:',
' 1 - 调用 deleteFile() 的语法或参数是否正确',
' 2 - 当前域名是否在安全域名列表中:https://console.cloud.tencent.com/tcb/env/safety',
' 3 - 云存储安全规则是否限制了当前登录状态访问',
`如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
]
})
public async deleteFile(
params: ICloudbaseDeleteFileParams,
callback?: Function
): Promise<ICloudbaseDeleteFileResult> {
const { fileList } = params;
if (!fileList || !isArray(fileList) || fileList.length === 0) {
throw new Error(JSON.stringify({
code: ERRORS.INVALID_PARAMS,
msg: `[${COMPONENT_NAME}.deleteFile] fileList must not be empty`
}));
}
for (const fileId of fileList) {
if (!fileId || !isString(fileId)) {
throw new Error(JSON.stringify({
code: ERRORS.INVALID_PARAMS,
msg: `[${COMPONENT_NAME}.deleteFile] fileID must be string`
}));
}
}
const action = 'storage.batchDeleteFile';
// @ts-ignore
const request = this.request;
const res = await request.send(action, {
fileid_list: fileList
});
if (res.code) {
return execCallback(callback, null, res);
}
const data = {
fileList: res.data.delete_list,
requestId: res.requestId
};
return execCallback(callback, null, data);;
}
@catchErrorsDecorator({
customInfo: {
className: 'Cloudbase',
methodName: 'getTempFileURL'
},
title: '获取文件下载链接',
messages: [
'请确认以下各项:',
' 1 - 调用 getTempFileURL() 的语法或参数是否正确',
' 2 - 当前域名是否在安全域名列表中:https://console.cloud.tencent.com/tcb/env/safety',
' 3 - 云存储安全规则是否限制了当前登录状态访问',
`如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
]
})
public async getTempFileURL(
params: ICloudbaseGetTempFileURLParams,
callback?: Function
): Promise<ICloudbaseGetTempFileURLResult> {
const { fileList } = params;
if (!fileList || !isArray(fileList) || fileList.length === 0) {
throw new Error(JSON.stringify({
code: ERRORS.INVALID_PARAMS,
msg: `[${COMPONENT_NAME}.getTempFileURL] fileList must not be empty`
}));
}
const file_list = [];
for (const file of fileList) {
if (isPalinObject(file)) {
if (!file.hasOwnProperty('fileID') || !file.hasOwnProperty('maxAge')) {
throw new Error(JSON.stringify({
code: ERRORS.INVALID_PARAMS,
msg: `[${COMPONENT_NAME}.getTempFileURL] file info must include fileID and maxAge`
}));
}
file_list.push({
fileid: (file as ICloudbaseFileInfo).fileID,
max_age: (file as ICloudbaseFileInfo).maxAge
});
} else if (isString(file)) {
file_list.push({
fileid: file
});
} else {
throw new Error(JSON.stringify({
code: ERRORS.INVALID_PARAMS,
msg: `[${COMPONENT_NAME}.getTempFileURL] invalid fileList`
}));
}
}
const action = 'storage.batchGetDownloadUrl';
// @ts-ignore
const request = this.request;
const res = await request.send(action, { file_list });
if (res.code) {
return execCallback(callback, null, res);
}
return execCallback(callback, null, {
fileList: res.data.download_list,
requestId: res.requestId
});
}
@catchErrorsDecorator({
customInfo: {
className: 'Cloudbase',
methodName: 'downloadFile'
},
title: '下载文件失败',
messages: [
'请确认以下各项:',
' 1 - 调用 downloadFile() 的语法或参数是否正确',
' 2 - 当前域名是否在安全域名列表中:https://console.cloud.tencent.com/tcb/env/safety',
' 3 - 云存储安全规则是否限制了当前登录状态访问',
`如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
]
})
public async downloadFile(
params: ICloudbaseDownloadFileParams,
callback?: Function
): Promise<ICloudbaseDownloadFileResult> {
const { fileID } = params;
if (!isString(fileID)) {
throw new Error(JSON.stringify({
code: ERRORS.INVALID_PARAMS,
msg: `[${COMPONENT_NAME}.getTempFileURL] fileID must be string`
}));
}
const tmpUrlRes = await this.getTempFileURL.call(this, {
fileList: [{
fileID,
maxAge: 600
}]
});
const res = tmpUrlRes.fileList[0];
if (res.code !== 'SUCCESS') {
return execCallback(callback, res);
}
// @ts-ignore
const request = this.request;
const tmpUrl = encodeURI(res.download_url);
const result = await request.download({ url: tmpUrl });
return execCallback(callback, null, result);
}
}
const cloudbaseStorage = new CloudbaseStorage();
const component: ICloudbaseComponent = {
name: COMPONENT_NAME,
entity: {
uploadFile: cloudbaseStorage.uploadFile,
deleteFile: cloudbaseStorage.deleteFile,
getTempFileURL: cloudbaseStorage.getTempFileURL,
downloadFile: cloudbaseStorage.downloadFile,
getUploadMetadata: cloudbaseStorage.getUploadMetadata
}
}
try {
cloudbase.registerComponent(component);
} catch (e) { }
export function registerStorage(app: Pick<ICloudbase, 'registerComponent'>) {
try {
app.registerComponent(component);
} catch (e) {
console.warn(e);
}
}