UNPKG

t-comm

Version:

专业、稳定、纯粹的工具库

227 lines (224 loc) 7.62 kB
import _regeneratorRuntime from '@babel/runtime/regenerator'; import { _ as __awaiter } from '../../tslib.es6-848120af.js'; import { getLocalFileMd5, getLocalFileSize } from '../../fs/fs.mjs'; import { getCOSInstance } from './helper.mjs'; import '../../nodejs/crypto.mjs'; import '../../nodejs/fs.mjs'; import '../../nodejs/os.mjs'; import '../../bite/format-bite.mjs'; import '../../third-party/cos-nodejs-sdk-v5.mjs'; /** * 获取腾讯云COS对象的元数据信息(不返回对象内容) * * @param secretId - 腾讯云API密钥ID * @param secretKey - 腾讯云API密钥Key * @param bucket - COS存储桶名称 * @param region - COS存储桶所在区域 * @param key - 对象键(Object Key),对象在存储桶中的唯一标识 * @returns Promise对象,成功时返回对象的元数据信息(如大小、修改时间等),失败时返回错误信息 * @throws 当参数不全时会抛出错误 * @example * ```typescript * getCosHeadObject({ * secretId: 'your-secret-id', * secretKey: 'your-secret-key', * bucket: 'test-bucket', * region: 'ap-beijing', * key: 'path/to/file.txt' * }) * .then(data => console.log(data)) * .catch(err => console.error(err)); * ``` */ function getCosHeadObject(_ref) { var secretId = _ref.secretId, secretKey = _ref.secretKey, bucket = _ref.bucket, region = _ref.region, key = _ref.key; return new Promise(function (resolve, reject) { if (!secretId || !secretKey || !bucket || !region) { reject('[Upload COS Error] 参数不全'); return; } var cos = getCOSInstance(secretId, secretKey); cos.headObject({ Bucket: bucket, Region: region, Key: key }, function (err, data) { if (data) { resolve(data); return; } reject(err || data); }); }); } /** * 下载腾讯云COS对象内容 * * @param secretId - 腾讯云API密钥ID * @param secretKey - 腾讯云API密钥Key * @param bucket - COS存储桶名称 * @param region - COS存储桶所在区域 * @param key - 对象键(Object Key),对象在存储桶中的唯一标识 * @param output - 输出路径或输出流,可选参数。如果指定,对象内容将写入该路径或流 * @returns Promise对象,成功时返回对象内容数据,失败时返回错误信息 * @throws 当参数不全时会抛出错误 * @example * ```typescript * // 下载到内存 * downloadCosObject({ * secretId: 'your-secret-id', * secretKey: 'your-secret-key', * bucket: 'test-bucket', * region: 'ap-beijing', * key: 'path/to/file.txt' * }) * .then(data => console.log(data)) * .catch(err => console.error(err)); * * // 下载到文件 * downloadCosObject({ * secretId: 'your-secret-id', * secretKey: 'your-secret-key', * bucket: 'test-bucket', * region: 'ap-beijing', * key: 'path/to/file.txt', * output: './local/file.txt' * }) * .then(data => console.log('下载成功')) * .catch(err => console.error(err)); * ``` */ function downloadCosObject(_ref2) { var secretId = _ref2.secretId, secretKey = _ref2.secretKey, bucket = _ref2.bucket, region = _ref2.region, key = _ref2.key, output = _ref2.output; return new Promise(function (resolve, reject) { if (!secretId || !secretKey || !bucket || !region) { reject('[Upload COS Error] 参数不全'); return; } var cos = getCOSInstance(secretId, secretKey); cos.getObject({ Bucket: bucket, Region: region, Key: key, Output: output }, function (err, data) { if (data) { resolve(data); return; } reject(err || data); }); }); } /** * 判断 COS 对象与本地文件是否一致(基于 size 与 ETag/MD5) * * 实现说明: * 1. 先比较文件大小(HEAD 返回的 Content-Length 与本地 stat().size);不一致直接判定为不同。 * 2. 大小一致时,再比较 MD5: * - 优先使用 COS 的 `x-cos-meta-md5`(上传时显式设置的元数据,最可靠); * - 否则使用 ETag(仅当对象为简单上传,即 ETag 不含连字符 `-` 时才视为整体 MD5;分块上传 ETag 不可用于直接比较)。 * * @param secretId - 腾讯云 API 密钥 ID * @param secretKey - 腾讯云 API 密钥 Key * @param bucket - COS 存储桶名称 * @param region - COS 存储桶所在区域 * @param key - 对象键 * @param localFilePath - 本地文件路径 * @returns {Promise<boolean>} 一致返回 true,否则 false(本地文件不存在或对象不存在也返回 false) * * @example * ```typescript * const same = await isCosObjectSameAsLocal({ * secretId, secretKey, * bucket: 'test-bucket', region: 'ap-beijing', * key: 'path/to/file.txt', * localFilePath: './local/file.txt', * }); * if (!same) { * // 重新上传 * } * ``` */ function isCosObjectSameAsLocal(_ref3) { var secretId = _ref3.secretId, secretKey = _ref3.secretKey, bucket = _ref3.bucket, region = _ref3.region, key = _ref3.key, localFilePath = _ref3.localFilePath; return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { var localSize, head, headers, remoteSize, remoteMetaMd5, localMd5, rawETag, etag, _localMd; return _regeneratorRuntime.wrap(function (_context) { while (1) switch (_context.prev = _context.next) { case 0: localSize = getLocalFileSize(localFilePath); if (!(localSize === null)) { _context.next = 1; break; } return _context.abrupt("return", false); case 1: _context.prev = 1; _context.next = 2; return getCosHeadObject({ secretId: secretId, secretKey: secretKey, bucket: bucket, region: region, key: key }); case 2: head = _context.sent; _context.next = 4; break; case 3: _context.prev = 3; _context["catch"](1); return _context.abrupt("return", false); case 4: headers = (head === null || head === void 0 ? void 0 : head.headers) || {}; remoteSize = Number(headers['content-length']); if (!(!Number.isFinite(remoteSize) || remoteSize !== localSize)) { _context.next = 5; break; } return _context.abrupt("return", false); case 5: // 1. 优先使用 x-cos-meta-md5 remoteMetaMd5 = headers['x-cos-meta-md5'] || ''; if (!remoteMetaMd5) { _context.next = 6; break; } localMd5 = getLocalFileMd5(localFilePath); return _context.abrupt("return", !!localMd5 && localMd5.toLowerCase() === remoteMetaMd5.toLowerCase()); case 6: // 2. 退化到 ETag(仅简单上传可作为 MD5 使用) rawETag = (head === null || head === void 0 ? void 0 : head.ETag) || headers.etag || ''; etag = rawETag.replace(/"/g, ''); if (!(etag && !etag.includes('-'))) { _context.next = 7; break; } _localMd = getLocalFileMd5(localFilePath); return _context.abrupt("return", !!_localMd && _localMd.toLowerCase() === etag.toLowerCase()); case 7: return _context.abrupt("return", false); case 8: case "end": return _context.stop(); } }, _callee, null, [[1, 3]]); })); } export { downloadCosObject, getCosHeadObject, isCosObjectSameAsLocal };