filestack-js
Version:
Official JavaScript library for Filestack
763 lines (762 loc) • 100 kB
JavaScript
import { __assign, __awaiter, __extends, __generator } from "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.
*/
import Debug from 'debug';
import PQueue from 'p-queue';
import { FilestackError, FilestackErrorType } from './../../../../filestack_error';
import { FsCancelToken, FsRequest, FsRequestError, FsRequestErrorCode } from './../../../request';
import { shouldRetry } from './../../../request/helpers';
import { filterObject, uniqueId, uniqueTime } from './../../../utils';
import { DEFAULT_STORE_LOCATION, INTELLIGENT_CHUNK_SIZE, MIN_CHUNK_SIZE, UploaderAbstract } from './abstract';
var debug = Debug('fs:upload:s3');
var COMPLETE_TIMEOUT = 1000 * 1;
var S3Uploader = /** @class */ (function (_super) {
__extends(S3Uploader, _super);
function S3Uploader(storeOptions, concurrency) {
var _this = _super.call(this, storeOptions, concurrency) || this;
_this.payloads = {};
_this.partsQueue = new PQueue({
autoStart: false,
concurrency: _this.concurrency,
});
_this.cancelToken = new 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 __awaiter(this, void 0, void 0, function () {
var tasks;
var _this = this;
return __generator(this, function (_a) {
tasks = Object.keys(this.payloads).map(function (id) {
return new Promise(function (resolve) { return __awaiter(_this, void 0, void 0, function () {
var e_1, file;
return __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(uniqueId(15), "_").concat(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 = __assign({ location: 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 = __assign(__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 __assign(__assign({}, 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 = 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] = __assign(__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 FilestackError("Invalid file \"".concat(payload.file.name, "\" size - 0"), {}, FilestackErrorType.VALIDATION));
}
debug("[".concat(id, "] Make start request"));
return FsRequest.post("".concat(this.getUrl(), "/multipart/start"), __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 FilestackError('Incorrect start response', data, 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 __awaiter(this, void 0, void 0, function () {
var payload, parts, waitingLength;
var _this = this;
return __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 __awaiter(_this, void 0, void 0, function () {
var _a;
var _this = this;
return __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 = __assign(__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 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 __awaiter(this, void 0, void 0, function () {
var payload, partMetadata, part, _a, data, headers;
var _this = this;
return __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*/, 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 FilestackError('Cannot upload file, check S3 bucket settings', 'Etag header is not exposed in CORS settings', 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 FilestackError('Cannot upload file', resp.data.Error, FilestackErrorType.REQUEST));
}
}
}
// release memory
part = null;
if (err instanceof 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 __awaiter(this, void 0, void 0, function () {
var _this = this;
return __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 __awaiter(this, void 0, void 0, function () {
var payload, part, chunk, data;
var _this = this;
return __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*/, 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 FilestackError('Cannot upload file', resp.data.Error, FilestackErrorType.REQUEST));
}
}
}
// reset progress on failed upload
_this.onProgressUpdate(id, partNumber, part.offset);
var nextChunkSize = Math.ceil(chunkSize / 2);
if (nextChunkSize < MIN_CHUNK_SIZE) {
debug("[".concat(id, "] Minimal chunk size limit. Upload file failed!"));
return Promise.reject(new FilestackError('Min chunk size reached', err.data, FilestackErrorType.REQUEST));
}
if (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 FsRequest.post("".concat(this.getUploadUrl(id), "/multipart/commit"), __assign(__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 FsRequest.post("".concat(this.getUploadUrl(id), "/multipart/complete"), __assign(__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] = __assign(__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 FsRequestError && err.code === FsRequestErrorCode.ABORTED) {
return Promise.reject(new FilestackError(message, { reason: err.message }, FilestackErrorType.ABORTED));
}
return Promise.reject(new FilestackError(message, this.parseError(err), FilestackErrorType.REQUEST));
};
return S3Uploader;
}(UploaderAbstract));
export { S3Uploader };
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvYXBpL3VwbG9hZC91cGxvYWRlcnMvczMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMxQixPQUFPLE1BQU0sTUFBTSxTQUFTLENBQUM7QUFFN0IsT0FBTyxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ25GLE9BQU8sRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBYyxNQUFNLG9CQUFvQixDQUFDO0FBQzlHLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUd0RSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsc0JBQXNCLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFjLE1BQU0sWUFBWSxDQUFDO0FBRTFILElBQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUVwQyxJQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUM7QUFtQmxDO0lBQWdDLDhCQUFnQjtJQU05QyxvQkFBWSxZQUFnQyxFQUFFLFdBQVk7UUFBMUQsWUFDRSxrQkFBTSxZQUFZLEVBQUUsV0FBVyxDQUFDLFNBUWpDO1FBWE8sY0FBUSxHQUFxQyxFQUFFLENBQUM7UUFLdEQsS0FBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLE1BQU0sQ0FBQztZQUMzQixTQUFTLEVBQUUsS0FBSztZQUNoQixXQUFXLEVBQUUsS0FBSSxDQUFDLFdBQVc7U0FDOUIsQ0FBQyxDQUFDO1FBRUgsS0FBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLGFBQWEsRUFBRSxDQUFDOztJQUN6QyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLDBCQUFLLEdBQVo7UUFDRSxJQUFJ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