UNPKG

filestack-js

Version:

Official JavaScript library for Filestack

766 lines (765 loc) 101 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.S3Uploader = void 0; var tslib_1 = require("tslib"); /* * Copyright (c) 2019 by Filestack. * Some rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var debug_1 = tslib_1.__importDefault(require("debug")); var p_queue_1 = tslib_1.__importDefault(require("p-queue")); var filestack_error_1 = require("./../../../../filestack_error"); var request_1 = require("./../../../request"); var helpers_1 = require("./../../../request/helpers"); var utils_1 = require("./../../../utils"); var abstract_1 = require("./abstract"); var debug = (0, debug_1.default)('fs:upload:s3'); var COMPLETE_TIMEOUT = 1000 * 1; var S3Uploader = /** @class */ (function (_super) { tslib_1.__extends(S3Uploader, _super); function S3Uploader(storeOptions, concurrency) { var _this = _super.call(this, storeOptions, concurrency) || this; _this.payloads = {}; _this.partsQueue = new p_queue_1.default({ autoStart: false, concurrency: _this.concurrency, }); _this.cancelToken = new request_1.FsCancelToken(); return _this; } /** * Pause upload queue * * @memberof S3Uploader */ S3Uploader.prototype.pause = function () { this.partsQueue.pause(); }; /** * resume upload queue if its paused * * @memberof S3Uploader */ S3Uploader.prototype.resume = function () { /* istanbul ignore next */ if (this.partsQueue.isPaused) { this.partsQueue.start(); } }; /** * Aborts queue (all pending requests with will be aborted) * * @memberof S3Uploader */ S3Uploader.prototype.abort = function (msg) { this.partsQueue.pause(); this.partsQueue.clear(); this.cancelToken.cancel(msg || 'Aborted by user'); }; /** * Execute all queued files * * @returns {Promise<any>} * @memberof S3Uploader */ S3Uploader.prototype.execute = function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var tasks; var _this = this; return tslib_1.__generator(this, function (_a) { tasks = Object.keys(this.payloads).map(function (id) { return new Promise(function (resolve) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var e_1, file; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 5, , 6]); return [4 /*yield*/, this.startRequest(id)]; case 1: _a.sent(); return [4 /*yield*/, this.prepareParts(id)]; case 2: _a.sent(); return [4 /*yield*/, this.startPartsQueue(id)]; case 3: _a.sent(); return [4 /*yield*/, this.completeRequest(id)]; case 4: _a.sent(); return [3 /*break*/, 6]; case 5: e_1 = _a.sent(); /* istanbul ignore next */ this.emit('error', e_1); debug("[".concat(id, "] File upload failed. %O, \nDetails: %O "), e_1.message, e_1.details); return [3 /*break*/, 6]; case 6: file = this.getPayloadById(id).file; // release file buffer file.release(); // cleanup payloads delete this.payloads[id]; resolve(file); return [2 /*return*/]; } }); }); }); }); return [2 /*return*/, Promise.all(tasks)]; }); }); }; /** * Add file to upload queue * * @param {File} file * @returns * @memberof S3Uploader */ S3Uploader.prototype.addFile = function (file) { debug('Add file to queue: \n %o', file); var id = "".concat((0, utils_1.uniqueId)(15), "_").concat((0, utils_1.uniqueTime)()); file.status = "Initialized" /* FileState.INIT */; // split file into parts and set it as waiting this.payloads[id] = { file: file, parts: [], }; return id; }; /** * Returns host for upload (region based) * * @private * @returns * @memberof S3Uploader */ S3Uploader.prototype.getUploadUrl = function (id) { var location_url = this.getDefaultFields(id, ['location_url']).location_url; return location_url.indexOf('http') === 0 ? location_url : "https://".concat(location_url); }; /** * Returns formatted store options * * @private * @returns * @memberof S3Uploader */ S3Uploader.prototype.getStoreOptions = function (id) { var options = tslib_1.__assign({ location: abstract_1.DEFAULT_STORE_LOCATION }, this.storeOptions); if (this.storeOptions.disableStorageKey) { var payload = this.getPayloadById(id); if (options.path && options.path.substr(-1) !== '/') { options.path = "".concat(options.path, "/"); } options.path = "".concat(options.path ? options.path : '/').concat(payload.file.name); delete options.disableStorageKey; } return options; }; /** * Returns all default fields for filestack requests * * @private * @returns * @memberof S3Uploader */ S3Uploader.prototype.getDefaultFields = function (id, requiredFields, fiiFallback) { if (fiiFallback === void 0) { fiiFallback = false; } var payload = this.getPayloadById(id); var fields = tslib_1.__assign(tslib_1.__assign({}, this.security), { apikey: this.apikey, uri: payload.uri, location_url: payload.location_url, upload_id: payload.upload_id, region: payload.region, alt: payload.file.alt }); if (this.uploadMode === "intelligent" /* UploadMode.INTELLIGENT */ || (this.uploadMode === "fallback" /* UploadMode.FALLBACK */ && fiiFallback)) { fields['fii'] = true; } return tslib_1.__assign(tslib_1.__assign({}, (0, utils_1.filterObject)(fields, requiredFields)), { store: this.getStoreOptions(id) }); }; /** * Returns default headers needed for filestack request * * @private * @returns * @memberof S3Uploader */ S3Uploader.prototype.getDefaultHeaders = function (id) { var headers = {}; var file = this.getPayloadById(id); if (file.location_region) { headers['Filestack-Upload-Region'] = file.location_region; } return headers; }; S3Uploader.prototype.getPayloadById = function (id) { return this.payloads[id]; }; /** * Split file onto parts for uploading with multipart mechanism and setup start * * @private * @memberof S3Uploader */ S3Uploader.prototype.prepareParts = function (id) { var file = this.getPayloadById(id).file; var intelligentChunk = false; // for intelligent or fallback mode we cant overwrite part size - requires 8MB if (["intelligent" /* UploadMode.INTELLIGENT */, "fallback" /* UploadMode.FALLBACK */].indexOf(this.uploadMode) > -1) { this.partSize = abstract_1.INTELLIGENT_CHUNK_SIZE; intelligentChunk = true; } var _a = file.getPartsCount(this.partSize, intelligentChunk), partsCount = _a.partsCount, chunkSize = _a.chunkSize; var parts = []; for (var i = 0; i < partsCount; i++) { parts[i] = tslib_1.__assign(tslib_1.__assign({}, file.getPartMetadata(i, chunkSize)), { offset: 0 }); } // split file into parts and set it as waiting this.payloads[id].parts = parts; return Promise.resolve(); }; /** * Make start request for getting needed upload fields * * @private * @returns {Promise<any>} * @memberof S3Uploader */ S3Uploader.prototype.startRequest = function (id) { var _this = this; var payload = this.getPayloadById(id); if (payload.file.size === 0) { this.setPayloadStatus(id, "Failed" /* FileState.FAILED */); return Promise.reject(new filestack_error_1.FilestackError("Invalid file \"".concat(payload.file.name, "\" size - 0"), {}, filestack_error_1.FilestackErrorType.VALIDATION)); } debug("[".concat(id, "] Make start request")); return request_1.FsRequest.post("".concat(this.getUrl(), "/multipart/start"), tslib_1.__assign({ filename: payload.file.name, mimetype: payload.file.type, size: payload.file.size }, this.getDefaultFields(id, ['apikey', 'policy', 'signature', 'fii'], true)), { timeout: this.timeout, cancelToken: this.cancelToken, headers: this.getDefaultHeaders(id), retry: this.retryConfig, }) .then(function (_a) { var data = _a.data; if (!data || !data.location_url || !data.region || !data.upload_id || !data.uri) { debug("[".concat(id, "] Incorrect start response: \n%O\n"), data); _this.setPayloadStatus(id, "Failed" /* FileState.FAILED */); return Promise.reject(new filestack_error_1.FilestackError('Incorrect start response', data, filestack_error_1.FilestackErrorType.REQUEST)); } debug("[".concat(id, "] Assign payload data: \n%O\n"), data); _this.updatePayload(id, data); // ii is not enabled in backend switch back to default upload mode if (["intelligent" /* UploadMode.INTELLIGENT */, "fallback" /* UploadMode.FALLBACK */].indexOf(_this.uploadMode) > -1 && (!data.upload_type || data.upload_type !== 'intelligent_ingestion')) { debug("[".concat(id, "] Intelligent Ingestion is not enabled on account, switch back to regular upload and lock mode change")); _this.setUploadMode("default" /* UploadMode.DEFAULT */, true); } return data; }) .catch(function (err) { debug("[".concat(id, "] Start request error %O"), err); _this.setPayloadStatus(id, "Failed" /* FileState.FAILED */); return _this.rejectUpload('Cannot upload file. Start request failed', err); }); }; /** * Enqueue file parts to upload * * @private * @returns * @memberof S3Uploader */ S3Uploader.prototype.startPartsQueue = function (id) { return tslib_1.__awaiter(this, void 0, void 0, function () { var payload, parts, waitingLength; var _this = this; return tslib_1.__generator(this, function (_a) { payload = this.getPayloadById(id); parts = payload.parts; waitingLength = parts.length; debug("[".concat(id, "] Create uploading queue from file. parts count - %d"), waitingLength); return [2 /*return*/, new Promise(function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var _a; var _this = this; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: parts.forEach(function (part) { return _this.partsQueue .add(function () { return _this.startPart(id, part.partNumber); }) .catch(function (e) { _this.setPayloadStatus(id, "Failed" /* FileState.FAILED */); debug("[".concat(id, "] Failed to upload part %s"), e.message); _this.partsQueue.pause(); _this.partsQueue.clear(); return reject(e); }); }); debug("[".concat(id, "] All tasks for %s enqueued. Start processing main upload queue"), id); this.emit('start'); this.partsQueue.start(); _a = resolve; return [4 /*yield*/, this.partsQueue.onIdle()]; case 1: _a.apply(void 0, [_b.sent()]); return [2 /*return*/]; } }); }); })]; }); }); }; /** * Decide if upload should be made using ii or regular upload * It allows change upload mode during upload queue * * @private * @param {number} partNumber * @returns {Promise<any>} * @memberof S3Uploader */ S3Uploader.prototype.startPart = function (id, partNumber) { debug("[".concat(id, "] Start processing part ").concat(partNumber, " with mode ").concat(this.uploadMode)); var payload = this.getPayloadById(id); payload.file.status = "Progress" /* FileState.PROGRESS */; return (this.uploadMode !== "intelligent" /* UploadMode.INTELLIGENT */ ? this.uploadRegular : this.uploadIntelligent).apply(this, [id, partNumber]); }; /** * Returns part data needed for upload * * @private * @param {string} id - id of a currently uploading file * @param {FilePart} part * @returns * @memberof S3Uploader */ S3Uploader.prototype.getS3PartMetadata = function (id, part, offset) { var _this = this; var url = this.getUploadUrl(id); debug("[".concat(id, "] Get data for part ").concat(part.partNumber, ", url ").concat(url, ", Md5: ").concat(part.md5, ", Size: ").concat(part.size)); var data = tslib_1.__assign(tslib_1.__assign({}, this.getDefaultFields(id, ['apikey', 'uri', 'region', 'signature', 'policy', 'upload_id', 'fii'])), { // method specific keys part: part.partNumber + 1, size: part.size, offset: offset }); if (this.integrityCheck && part.md5) { data.md5 = part.md5; } return request_1.FsRequest.post("".concat(url, "/multipart/upload"), data, { headers: this.getDefaultHeaders(id), cancelToken: this.cancelToken, timeout: this.timeout, retry: this.retryConfig, }).catch(function (err) { _this.setPayloadStatus(id, "Failed" /* FileState.FAILED */); return _this.rejectUpload('Cannot get part metadata', err); }); }; /** * Regular multipart request to amazon * * @private * @param {number} partNumber * @returns {Promise<any>} * @memberof S3Uploader */ S3Uploader.prototype.uploadRegular = function (id, partNumber) { return tslib_1.__awaiter(this, void 0, void 0, function () { var payload, partMetadata, part, _a, data, headers; var _this = this; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: payload = this.getPayloadById(id); partMetadata = payload.parts[partNumber]; return [4 /*yield*/, payload.file.getPartByMetadata(partMetadata, this.integrityCheck)]; case 1: part = _b.sent(); return [4 /*yield*/, this.getS3PartMetadata(id, part)]; case 2: _a = _b.sent(), data = _a.data, headers = _a.headers; debug("[".concat(id, "] Received part ").concat(partNumber, " info body: \n%O\n headers: \n%O\n"), data, headers); return [2 /*return*/, request_1.FsRequest.put(data.url, part.buffer, { cancelToken: this.cancelToken, timeout: this.timeout, headers: data.headers, filestackHeaders: false, // for now we cant test progress callback from upload /* istanbul ignore next */ onProgress: function (pr) { return _this.onProgressUpdate(id, partNumber, pr.loaded); }, retry: this.retryConfig && this.uploadMode !== "fallback" /* UploadMode.FALLBACK */ ? this.retryConfig : undefined, }) .then(function (res) { if (res.headers.etag) { _this.setPartETag(id, partNumber, res.headers.etag); } else { // release memory part = null; throw new filestack_error_1.FilestackError('Cannot upload file, check S3 bucket settings', 'Etag header is not exposed in CORS settings', filestack_error_1.FilestackErrorType.REQUEST); } debug("[".concat(id, "] S3 Upload response headers for ").concat(partNumber, ": \n%O\n"), res.headers); _this.onProgressUpdate(id, partNumber, part.size); // release memory part = null; return res; }) .catch(function (err) { var resp = err && err.response ? err.response : null; /* istanbul ignore next */ if (resp && resp.status === 403) { if (resp.data && resp.data.Error && resp.data.Error.code) { var code = resp.data.Error.code; if (Array.isArray(code)) { code = code.pop(); } switch (code) { case 'RequestTimeTooSkewed': return _this.startPart(id, partNumber); default: return Promise.reject(new filestack_error_1.FilestackError('Cannot upload file', resp.data.Error, filestack_error_1.FilestackErrorType.REQUEST)); } } } // release memory part = null; if (err instanceof filestack_error_1.FilestackError) { return Promise.reject(err); } // reset upload progress on failed part _this.onProgressUpdate(id, partNumber, 0); // if fallback, set upload mode to intelligent and restart current part if ((_this.uploadMode === "fallback" /* UploadMode.FALLBACK */ && !_this.isModeLocked) || _this.uploadMode === "intelligent" /* UploadMode.INTELLIGENT */) { debug("[".concat(id, "] Regular upload failed. Switching to intelligent ingestion mode")); _this.setUploadMode("intelligent" /* UploadMode.INTELLIGENT */); // restart part return _this.startPart(id, partNumber); } return _this.rejectUpload('Cannot upload file part', err); })]; } }); }); }; /** * Upload file using intelligent mechanism * * @private * @param {string} id * @param {number} partNumber * @returns {Promise<any>} * @memberof S3Uploader */ S3Uploader.prototype.uploadIntelligent = function (id, partNumber) { return tslib_1.__awaiter(this, void 0, void 0, function () { var _this = this; return tslib_1.__generator(this, function (_a) { return [2 /*return*/, this.uploadNextChunk(id, partNumber).then(function () { return _this.commitPart(id, partNumber); })]; }); }); }; /** * Recursively upload file in chunk mode (intelligent ingession) * * @private * @param {string} id * @param {number} partNumber * @param {number} chunkSize * @returns * @memberof S3Uploader */ S3Uploader.prototype.uploadNextChunk = function (id, partNumber, chunkSize) { if (chunkSize === void 0) { chunkSize = this.intelligentChunkSize; } return tslib_1.__awaiter(this, void 0, void 0, function () { var payload, part, chunk, data; var _this = this; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: payload = this.getPayloadById(id); part = payload.parts[partNumber]; chunkSize = part.size - part.offset; return [4 /*yield*/, payload.file.getChunkByMetadata(part, part.offset, chunkSize, this.integrityCheck)]; case 1: chunk = _a.sent(); debug("[".concat(id, "] PartNum: ").concat(partNumber, ", PartSize: ").concat(part.size, ", StartByte: ").concat(part.startByte, ", Offset: ").concat(part.offset, ", ChunkSize: ").concat(chunk.size, ",\n Left: ").concat(part.size - part.offset - chunk.size)); return [4 /*yield*/, this.getS3PartMetadata(id, chunk, part.offset).catch(function (err) { debug("[".concat(id, "] Getting chunk data for ii failed %O, Chunk size: ").concat(chunkSize, ", offset ").concat(part.offset, ", part ").concat(partNumber), err); return Promise.reject(err); })]; case 2: data = (_a.sent()).data; return [2 /*return*/, request_1.FsRequest.put(data.url, chunk.buffer, { cancelToken: this.cancelToken, timeout: this.timeout, headers: data.headers, filestackHeaders: false, // for now we cant test progress callback from upload /* istanbul ignore next */ onProgress: function (pr) { return part ? _this.onProgressUpdate(id, partNumber, part.offset + pr.loaded) : null; }, }) .then(function (res) { _this.onProgressUpdate(id, partNumber, part.offset + chunk.size); var newOffset = Math.min(part.offset + chunkSize, part.size); debug("[".concat(id, "] S3 Chunk uploaded! offset: ").concat(part.offset, ", part ").concat(partNumber, "! response headers for ").concat(partNumber, ": \n%O\n"), res.headers); _this.setPartData(id, partNumber, 'offset', newOffset); // if all chunks was uploaded then return resolve if (newOffset === part.size) { return Promise.resolve(res); } // release memory part = null; chunk = null; return _this.uploadNextChunk(id, partNumber, chunkSize); }) .catch(function (err) { var resp = err && err.response ? err.response : null; /* istanbul ignore next */ if (resp && resp.status === 403) { if (resp.data && resp.data.Error && resp.data.Error.code) { var code = resp.data.Error.code; if (Array.isArray(code)) { code = code.pop(); } switch (code) { case 'RequestTimeTooSkewed': return _this.startPart(id, partNumber); default: return Promise.reject(new filestack_error_1.FilestackError('Cannot upload file', resp.data.Error, filestack_error_1.FilestackErrorType.REQUEST)); } } } // reset progress on failed upload _this.onProgressUpdate(id, partNumber, part.offset); var nextChunkSize = Math.ceil(chunkSize / 2); if (nextChunkSize < abstract_1.MIN_CHUNK_SIZE) { debug("[".concat(id, "] Minimal chunk size limit. Upload file failed!")); return Promise.reject(new filestack_error_1.FilestackError('Min chunk size reached', err.data, filestack_error_1.FilestackErrorType.REQUEST)); } if ((0, helpers_1.shouldRetry)(err)) { debug("[".concat(id, "] Request network error. Retry with new chunk size: ").concat(nextChunkSize)); return _this.uploadNextChunk(id, partNumber, nextChunkSize); } // release memory part = null; chunk = null; return _this.rejectUpload('Cannot upload file part (FII)', err); })]; } }); }); }; /** * Commit after upload all chunks of the part in ii mode * * @private * @param {string} id * @param {FilePart} part * @returns * @memberof S3Uploader */ S3Uploader.prototype.commitPart = function (id, partNumber) { var _this = this; var payload = this.getPayloadById(id); var part = payload.parts[partNumber]; return request_1.FsRequest.post("".concat(this.getUploadUrl(id), "/multipart/commit"), tslib_1.__assign(tslib_1.__assign({}, this.getDefaultFields(id, ['apikey', 'region', 'upload_id', 'policy', 'signature', 'uri'])), { size: payload.file.size, part: part.partNumber + 1 }), { cancelToken: this.cancelToken, timeout: this.timeout, headers: this.getDefaultHeaders(id), retry: this.retryConfig, }) .then(function (res) { debug("[".concat(id, "] Commit Part number ").concat(part.partNumber, ". Response: %O"), res.data); return res; }) .catch(function (err) { return _this.rejectUpload('Cannot commit file part metadata', err); }); }; /** * Complete request to merge all parts and get file handle etc * * @private * @returns * @memberof S3Uploader */ S3Uploader.prototype.completeRequest = function (id) { var _this = this; var payload = this.getPayloadById(id); var parts = []; debug("[".concat(id, "] Run complete request")); var partsHandle = payload.parts; var partLen = partsHandle.length; for (var i = 0; i < partLen; i++) { if (partsHandle[i].etag) { parts.push({ part_number: i + 1, etag: partsHandle[i].etag }); } } debug("[".concat(id, "] Etags %O"), parts); return request_1.FsRequest.post("".concat(this.getUploadUrl(id), "/multipart/complete"), tslib_1.__assign(tslib_1.__assign({}, this.getDefaultFields(id, ['apikey', 'policy', 'signature', 'uri', 'region', 'upload_id', 'fii', 'alt'], true)), { // method specific keys filename: payload.file.name, mimetype: payload.file.type, size: payload.file.size, upload_tags: this.uploadTags && Object.keys(this.uploadTags).length ? this.uploadTags : undefined, parts: parts.length ? parts : undefined }), { timeout: this.timeout, cancelToken: this.cancelToken, headers: this.getDefaultHeaders(id), retry: this.retryConfig, }) .then(function (res) { // if parts hasnt been merged, retry complete request again if (res.status === 202) { return new Promise(function (resolve, reject) { setTimeout(function () { return _this.completeRequest(id) .then(resolve) .catch(reject); }, COMPLETE_TIMEOUT); }); } // update file object var file = _this.getPayloadById(id).file; file.handle = res.data.handle; file.url = res.data.url; file.container = res.data.container; file.key = res.data.key; file.uploadTags = res.data.upload_tags; file.workflows = res.data.workflows; file.status = res.data.status; return file; }) .catch(function (err) { _this.setPayloadStatus(id, "Failed" /* FileState.FAILED */); return _this.rejectUpload('Cannot complete file', err); }); }; /** * UUpgrade upload progress and run progress event * * @private * @param {string} id * @param {number} partNumber * @param {number} loaded * @memberof S3Uploader */ S3Uploader.prototype.onProgressUpdate = function (id, partNumber, loaded) { this.setPartData(id, partNumber, 'progress', loaded); this.emitProgress(); }; /** * Emits normalized progress event * * @private * @memberof S3Uploader */ S3Uploader.prototype.emitProgress = function () { var totalSize = 0; var totalBytes = 0; var filesProgress = {}; for (var i in this.payloads) { var payload = this.payloads[i]; // omit all failed files in progress event // this shouldn't happend because of promises rejection in execute. Left to be sure /* istanbul ignore next */ if (payload.file.status === "Failed" /* FileState.FAILED */) { continue; } var totalParts = payload.parts.map(function (p) { return p.progress || 0; }).reduce(function (a, b) { return a + b; }, 0); totalBytes = totalBytes + totalParts; filesProgress[i] = { totalBytes: totalParts, totalPercent: Math.round((totalParts * 100) / payload.file.size) || 0, }; totalSize = totalSize + payload.file.size; } var res = { totalBytes: totalBytes || 0, totalPercent: Math.round((totalBytes * 100) / totalSize) || 0, files: filesProgress, }; debug("Upload progress %O", res); this.emit('progress', res); }; /** * Apply provided data to given payload * * @private * @param {string} id * @param {*} data * @memberof S3Uploader */ S3Uploader.prototype.updatePayload = function (id, data) { this.payloads[id] = tslib_1.__assign(tslib_1.__assign({}, this.payloads[id]), data); }; /** * Sets etag for part * * @private * @param {number} partNumber * @param {string} etag * @memberof S3Uploader */ S3Uploader.prototype.setPartETag = function (id, partNumber, etag) { debug("[".concat(id, "] Set ").concat(etag, " etag for part ").concat(partNumber)); this.getPayloadById(id).parts[partNumber].etag = etag; }; /** * Sets part value for a key * * @private * @param {number} partNumber * @param {string} etag * @memberof S3Uploader */ S3Uploader.prototype.setPartData = function (id, partNumber, key, value) { debug("[".concat(id, "] Set ").concat(key, " = ").concat(value, " for part ").concat(partNumber)); var payload = this.getPayloadById(id); /* istanbul ignore next */ if (!payload) { debug("[".concat(id, "] Cannot set ").concat(key, " = ").concat(value, " for part ").concat(partNumber)); return; } payload.parts[partNumber][key] = value; }; /** * Set payload file state * * @param id * @param status */ S3Uploader.prototype.setPayloadStatus = function (id, status) { debug("[".concat(id, "] Set payload status to ").concat(status)); /* istanbul ignore next: additional check in case if file will be deleted before setting status */ if (!this.payloads[id]) { return; } this.payloads[id].file.status = status; }; /** * Returns error details if response exists * * @param err */ S3Uploader.prototype.parseError = function (err) { if (!err.response) { return {}; } return { code: err.response.status, data: err.response.data, headers: err.response.headers, }; }; S3Uploader.prototype.rejectUpload = function (message, err) { if (err instanceof request_1.FsRequestError && err.code === request_1.FsRequestErrorCode.ABORTED) { return Promise.reject(new filestack_error_1.FilestackError(message, { reason: err.message }, filestack_error_1.FilestackErrorType.ABORTED)); } return Promise.reject(new filestack_error_1.FilestackError(message, this.parseError(err), filestack_error_1.FilestackErrorType.REQUEST)); }; return S3Uploader; }(abstract_1.UploaderAbstract)); exports.S3Uploader = S3Uploader; //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvYXBpL3VwbG9hZC91cGxvYWRlcnMvczMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILHdEQUEwQjtBQUMxQiw0REFBNkI7QUFFN0IsaUVBQW1GO0FBQ25GLDhDQUE4RztBQUM5RyxzREFBeUQ7QUFDekQsMENBQXNFO0FBR3RFLHVDQUEwSDtBQUUxSCxJQUFNLEtBQUssR0FBRyxJQUFBLGVBQUssRUFBQyxjQUFjLENBQUMsQ0FBQztBQUVwQyxJQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUM7QUFtQmxDO0lBQWdDLHNDQUFnQjtJQU05QyxvQkFBWSxZQUFnQyxFQUFFLFdBQVk7UUFBMUQsWUFDRSxrQkFBTSxZQUFZLEVBQUUsV0FBVyxDQUFDLFNBUWpDO1FBWE8sY0FBUSxHQUFxQyxFQUFFLENBQUM7UUFLdEQsS0FBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLGlCQUFNLENBQUM7WUFDM0IsU0FBUyxFQUFFLEtBQUs7WUFDaEIsV0FBVyxFQUFFLEtBQUksQ0FBQyxXQUFXO1NBQzlCLENBQUMsQ0FBQztRQUVILEtBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSx1QkFBYSxFQUFFLENBQUM7O0lBQ3pDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksMEJBQUssR0FBWjtRQUNFLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSwyQkFBTSxHQUFiO1FBQ0UsMEJBQTBCO1FBQzFCLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUU7WUFDNUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztTQUN6QjtJQUNILENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksMEJBQUssR0FBWixVQUFhLEdBQVk7UUFDdkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN4QixJQUFJLENB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