UNPKG

@nos-sdk/nos-node-sdk

Version:

NOS Node.js SDK实现了NOS对象操作接口,基于此SDK能方便快速地实现JavaScript应用程序来使用NOS的对象存储服务。

234 lines 10.8 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const date_fns_1 = require("date-fns"); const fs = __importStar(require("fs")); const ramda_1 = require("ramda"); const util = __importStar(require("util")); const client_1 = require("../client"); const constant_1 = require("../lib/constant"); const util_1 = require("../lib/util"); class NosClientMultipartUploadExt extends client_1.NosBaseClient { initMultipartUpload(params) { return __awaiter(this, void 0, void 0, function* () { const { bucket, headers, resource } = this.validateParams(params); Object.assign(resource, { uploads: true, }); const result = yield this.requestBody('post', headers, resource); return result.initiateMultipartUploadResult.uploadId; }); } abortMultipartUpload(params) { return __awaiter(this, void 0, void 0, function* () { const { bucket, headers, resource } = this.validateParams(params); Object.assign(resource, { uploadId: params.uploadId, }); const result = yield this.requestBody('delete', headers, resource); return true; }); } uploadMultipart(params) { return __awaiter(this, void 0, void 0, function* () { const { bucket, headers, resource } = this.validateParams(params); Object.assign(resource, { partNumber: params.partNumber, uploadId: params.uploadId, }); const resp = yield this.request('put', headers, resource, params.body); let eTag = resp.headers.get('etag'); if (eTag.charAt(0) === '\"' && eTag.charAt(eTag.length - 1) === '\"') { eTag = eTag.slice(1, -1); } return { partNumber: params.partNumber, eTag: eTag, size: params.body.length, lastModified: date_fns_1.parse(resp.headers.get('date')), }; }); } listParts(params) { return __awaiter(this, void 0, void 0, function* () { const { bucket, headers, resource } = this.validateParams(params); Object.assign(resource, util_1.compactObject({ uploadId: params.uploadId, 'max-parts': params.limit, 'part-number-marker': params.marker, })); const { listPartsResult: result } = yield this.requestBody('get', headers, resource); let parts = result.part; if (ramda_1.type(parts) !== 'Array') { parts = [parts]; } for (const part of parts) { part.lastModified = date_fns_1.parse(part.lastModified); } return Object.assign({}, ramda_1.pick(['isTruncated', 'owner', 'storageClass', 'bucket'], result), { limit: result.maxParts, nextMarker: result.nextPartNumberMarker, items: parts }); }); } listMultipartUpload(params = {}) { return __awaiter(this, void 0, void 0, function* () { const { bucket, headers, resource } = this.validateParams(params); Object.assign(resource, util_1.compactObject({ uploads: true, prefix: params.prefix, 'key-marker': params.marker, 'max-uploads': params.limit, })); if (params.limit) { headers['max-uploads'] = params.limit; } const { listMultipartUploadsResult: result } = yield this.requestBody('get', headers, resource); let uploads = util_1.normalizeArray(result.upload); if (ramda_1.type(uploads) !== 'Array') { uploads = [uploads]; } for (const upload of uploads) { upload.initiated = date_fns_1.parse(upload.initiated); } return Object.assign({}, ramda_1.pick(['isTruncated'], result), { items: uploads, nextMarker: result.nextKeyMarker, bucket: result.bucket, limit: params.limit || 1000 }); }); } completeMultipartUpload(params) { return __awaiter(this, void 0, void 0, function* () { const { bucket, headers, resource } = this.validateParams(params); Object.assign(resource, { uploadId: params.uploadId, }); const result = yield this.requestBody('post', headers, resource, { completeMultipartUpload: { part: params.parts.map(part => ({ partNumber: part.partNumber, eTag: part.eTag })), }, }); return result.completeMultipartUploadResult; }); } putBigObject(params) { return __awaiter(this, void 0, void 0, function* () { const uploadId = yield this.initMultipartUpload(params); const stream = 'body' in params ? params.body : fs.createReadStream(params.file); const lengthComputable = 'file' in params; const { parallel = Infinity, maxPart = constant_1.MAX_PART_LENGTH } = params; let totalLength = 0; if ('file' in params) { const stat = yield util.promisify(fs.stat)(params.file); totalLength = stat.size; } const rootParams = { uploadId, objectKey: params.objectKey, bucket: params.bucket, }; const bufs = []; const partPromises = []; let length = 0; let partNumber = 1; let aborted = false; let uploadedLength = 0; let onProgress = params.onProgress; let workers = 0; const uploadPart = () => __awaiter(this, void 0, void 0, function* () { const tBuf = Buffer.concat(bufs); const tPartNumber = partNumber++; bufs.length = 0; length = 0; if (++workers >= parallel) { stream.pause(); } const part = yield this.uploadMultipart(Object.assign({}, rootParams, { partNumber: tPartNumber, body: tBuf })); workers--; if (stream.isPaused()) { stream.resume(); } uploadedLength += tBuf.length; if (onProgress) { onProgress({ lengthComputable, uploaded: uploadedLength, total: totalLength, }); } return part; }); return yield new Promise((resolve, reject) => { const completeUpload = () => __awaiter(this, void 0, void 0, function* () { const parts = yield Promise.all(partPromises); const resp = yield this.completeMultipartUpload(Object.assign({}, rootParams, { parts })); resolve(resp); }); const abortUpload = (e) => { if (aborted) { return; } stream.removeListener('data', onData); aborted = true; reject(e); }; const onData = (data) => { if (data.length + length > maxPart) { const partPromise = uploadPart(); partPromise.catch(abortUpload); partPromises.push(partPromise); } bufs.push(data); length += data.length; }; stream.on('data', onData); stream.once('end', () => { if (length) { const partPromise = uploadPart(); partPromise.catch(abortUpload); partPromises.push(partPromise); } completeUpload().catch(abortUpload); }); stream.once('error', abortUpload); }); }); } } __decorate([ util_1.Callbackable ], NosClientMultipartUploadExt.prototype, "initMultipartUpload", null); __decorate([ util_1.Callbackable ], NosClientMultipartUploadExt.prototype, "abortMultipartUpload", null); __decorate([ util_1.Callbackable ], NosClientMultipartUploadExt.prototype, "uploadMultipart", null); __decorate([ util_1.Callbackable ], NosClientMultipartUploadExt.prototype, "listParts", null); __decorate([ util_1.Callbackable ], NosClientMultipartUploadExt.prototype, "listMultipartUpload", null); __decorate([ util_1.Callbackable ], NosClientMultipartUploadExt.prototype, "completeMultipartUpload", null); __decorate([ util_1.Callbackable ], NosClientMultipartUploadExt.prototype, "putBigObject", null); exports.NosClientMultipartUploadExt = NosClientMultipartUploadExt; //# sourceMappingURL=multipart-upload.js.map