"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UploadService = exports.NotCancellableError = exports.UploadPreviouslyFinalizedError = exports.UploadNotActiveError = exports.UploadStatus = exports.UploadType = void 0; const uuid_1 = require("uuid"); const errors_1 = require("./errors"); var UploadType; (function (UploadType) { UploadType[UploadType["MEDIA"] = 0] = "MEDIA"; UploadType[UploadType["MULTIPART"] = 1] = "MULTIPART"; UploadType[UploadType["RESUMABLE"] = 2] = "RESUMABLE"; })(UploadType = exports.UploadType || (exports.UploadType = {})); var UploadStatus; (function (UploadStatus) { UploadStatus["ACTIVE"] = "active"; UploadStatus["CANCELLED"] = "cancelled"; UploadStatus["FINISHED"] = "final"; })(UploadStatus = exports.UploadStatus || (exports.UploadStatus = {})); class UploadNotActiveError extends Error { } exports.UploadNotActiveError = UploadNotActiveError; class UploadPreviouslyFinalizedError extends Error { } exports.UploadPreviouslyFinalizedError = UploadPreviouslyFinalizedError; class NotCancellableError extends Error { } exports.NotCancellableError = NotCancellableError; class UploadService { constructor(_persistence) { this._persistence = _persistence; this.reset(); } reset() { this._uploads = new Map(); } mediaUpload(request) { const upload = this.startOneShotUpload({ bucketId: request.bucketId, objectId: request.objectId, uploadType: UploadType.MEDIA, dataRaw: request.dataRaw, authorization: request.authorization, }); this._persistence.deleteFile(upload.path, true); this._persistence.appendBytes(upload.path, request.dataRaw); return upload; } multipartUpload(request) { const upload = this.startOneShotUpload({ bucketId: request.bucketId, objectId: request.objectId, uploadType: UploadType.MULTIPART, dataRaw: request.dataRaw, metadata: request.metadata, authorization: request.authorization, }); this._persistence.deleteFile(upload.path, true); this._persistence.appendBytes(upload.path, request.dataRaw); return upload; } startOneShotUpload(request) { const id = (0, uuid_1.v4)(); const upload = { id, bucketId: request.bucketId, objectId: request.objectId, type: request.uploadType, path: this.getStagingFileName(id, request.bucketId, request.objectId), status: UploadStatus.FINISHED, metadata: request.metadata, size: request.dataRaw.byteLength, authorization: request.authorization, }; this._uploads.set(upload.id, upload); return upload; } startResumableUpload(request) { const id = (0, uuid_1.v4)(); const upload = { id: id, bucketId: request.bucketId, objectId: request.objectId, type: UploadType.RESUMABLE, path: this.getStagingFileName(id, request.bucketId, request.objectId), status: UploadStatus.ACTIVE, metadata: request.metadata, size: 0, authorization: request.authorization, }; this._uploads.set(upload.id, upload); this._persistence.deleteFile(upload.path, true); this._persistence.appendBytes(upload.path, Buffer.alloc(0)); return upload; } continueResumableUpload(uploadId, dataRaw) { const upload = this.getResumableUpload(uploadId); if (upload.status !== UploadStatus.ACTIVE) { throw new UploadNotActiveError(); } this._persistence.appendBytes(upload.path, dataRaw); upload.size += dataRaw.byteLength; return upload; } getResumableUpload(uploadId) { const upload = this._uploads.get(uploadId); if (!upload || upload.type !== UploadType.RESUMABLE) { throw new errors_1.NotFoundError(); } return upload; } cancelResumableUpload(uploadId) { const upload = this.getResumableUpload(uploadId); if (upload.status === UploadStatus.FINISHED) { throw new NotCancellableError(); } upload.status = UploadStatus.CANCELLED; return upload; } finalizeResumableUpload(uploadId) { const upload = this.getResumableUpload(uploadId); if (upload.status === UploadStatus.FINISHED) { throw new UploadPreviouslyFinalizedError(); } if (upload.status === UploadStatus.CANCELLED) { throw new UploadNotActiveError(); } upload.status = UploadStatus.FINISHED; return upload; } setResponseCode(uploadId, code) { const upload = this._uploads.get(uploadId); if (upload) { upload.prevResponseCode = code; } } getPreviousResponseCode(uploadId) { var _a; return ((_a = this._uploads.get(uploadId)) === null || _a === void 0 ? void 0 : _a.prevResponseCode) || 200; } getStagingFileName(uploadId, bucketId, objectId) { return encodeURIComponent(`${uploadId}_b_${bucketId}_o_${objectId}`); } } exports.UploadService = UploadService;