UNPKG

@cloudbase/storage

Version:
320 lines (292 loc) 9.95 kB
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); } }