No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

upload.js 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.UploadService = exports.NotCancellableError = exports.UploadPreviouslyFinalizedError = exports.UploadNotActiveError = exports.UploadStatus = exports.UploadType = void 0;
  4. const uuid_1 = require("uuid");
  5. const errors_1 = require("./errors");
  6. var UploadType;
  7. (function (UploadType) {
  8. UploadType[UploadType["MEDIA"] = 0] = "MEDIA";
  9. UploadType[UploadType["MULTIPART"] = 1] = "MULTIPART";
  10. UploadType[UploadType["RESUMABLE"] = 2] = "RESUMABLE";
  11. })(UploadType = exports.UploadType || (exports.UploadType = {}));
  12. var UploadStatus;
  13. (function (UploadStatus) {
  14. UploadStatus[UploadStatus["ACTIVE"] = 0] = "ACTIVE";
  15. UploadStatus[UploadStatus["CANCELLED"] = 1] = "CANCELLED";
  16. UploadStatus[UploadStatus["FINISHED"] = 2] = "FINISHED";
  17. })(UploadStatus = exports.UploadStatus || (exports.UploadStatus = {}));
  18. class UploadNotActiveError extends Error {
  19. }
  20. exports.UploadNotActiveError = UploadNotActiveError;
  21. class UploadPreviouslyFinalizedError extends Error {
  22. }
  23. exports.UploadPreviouslyFinalizedError = UploadPreviouslyFinalizedError;
  24. class NotCancellableError extends Error {
  25. }
  26. exports.NotCancellableError = NotCancellableError;
  27. class UploadService {
  28. constructor(_persistence) {
  29. this._persistence = _persistence;
  30. this.reset();
  31. }
  32. reset() {
  33. this._uploads = new Map();
  34. }
  35. mediaUpload(request) {
  36. const upload = this.startOneShotUpload({
  37. bucketId: request.bucketId,
  38. objectId: request.objectId,
  39. uploadType: UploadType.MEDIA,
  40. dataRaw: request.dataRaw,
  41. authorization: request.authorization,
  42. });
  43. this._persistence.deleteFile(upload.path, true);
  44. this._persistence.appendBytes(upload.path, request.dataRaw);
  45. return upload;
  46. }
  47. multipartUpload(request) {
  48. const upload = this.startOneShotUpload({
  49. bucketId: request.bucketId,
  50. objectId: request.objectId,
  51. uploadType: UploadType.MULTIPART,
  52. dataRaw: request.dataRaw,
  53. metadata: request.metadata,
  54. authorization: request.authorization,
  55. });
  56. this._persistence.deleteFile(upload.path, true);
  57. this._persistence.appendBytes(upload.path, request.dataRaw);
  58. return upload;
  59. }
  60. startOneShotUpload(request) {
  61. const id = (0, uuid_1.v4)();
  62. const upload = {
  63. id,
  64. bucketId: request.bucketId,
  65. objectId: request.objectId,
  66. type: request.uploadType,
  67. path: this.getStagingFileName(id, request.bucketId, request.objectId),
  68. status: UploadStatus.FINISHED,
  69. metadata: request.metadata,
  70. size: request.dataRaw.byteLength,
  71. authorization: request.authorization,
  72. };
  73. this._uploads.set(upload.id, upload);
  74. return upload;
  75. }
  76. startResumableUpload(request) {
  77. const id = (0, uuid_1.v4)();
  78. const upload = {
  79. id: id,
  80. bucketId: request.bucketId,
  81. objectId: request.objectId,
  82. type: UploadType.RESUMABLE,
  83. path: this.getStagingFileName(id, request.bucketId, request.objectId),
  84. status: UploadStatus.ACTIVE,
  85. metadata: request.metadata,
  86. size: 0,
  87. authorization: request.authorization,
  88. };
  89. this._uploads.set(upload.id, upload);
  90. this._persistence.deleteFile(upload.path, true);
  91. this._persistence.appendBytes(upload.path, Buffer.alloc(0));
  92. return upload;
  93. }
  94. continueResumableUpload(uploadId, dataRaw) {
  95. const upload = this.getResumableUpload(uploadId);
  96. if (upload.status !== UploadStatus.ACTIVE) {
  97. throw new UploadNotActiveError();
  98. }
  99. this._persistence.appendBytes(upload.path, dataRaw);
  100. upload.size += dataRaw.byteLength;
  101. return upload;
  102. }
  103. getResumableUpload(uploadId) {
  104. const upload = this._uploads.get(uploadId);
  105. if (!upload || upload.type !== UploadType.RESUMABLE) {
  106. throw new errors_1.NotFoundError();
  107. }
  108. return upload;
  109. }
  110. cancelResumableUpload(uploadId) {
  111. const upload = this.getResumableUpload(uploadId);
  112. if (upload.status === UploadStatus.FINISHED) {
  113. throw new NotCancellableError();
  114. }
  115. upload.status = UploadStatus.CANCELLED;
  116. return upload;
  117. }
  118. finalizeResumableUpload(uploadId) {
  119. const upload = this.getResumableUpload(uploadId);
  120. if (upload.status === UploadStatus.FINISHED) {
  121. throw new UploadPreviouslyFinalizedError();
  122. }
  123. if (upload.status === UploadStatus.CANCELLED) {
  124. throw new UploadNotActiveError();
  125. }
  126. upload.status = UploadStatus.FINISHED;
  127. return upload;
  128. }
  129. setResponseCode(uploadId, code) {
  130. const upload = this._uploads.get(uploadId);
  131. if (upload) {
  132. upload.prevResponseCode = code;
  133. }
  134. }
  135. getPreviousResponseCode(uploadId) {
  136. var _a;
  137. return ((_a = this._uploads.get(uploadId)) === null || _a === void 0 ? void 0 : _a.prevResponseCode) || 200;
  138. }
  139. getStagingFileName(uploadId, bucketId, objectId) {
  140. return encodeURIComponent(`${uploadId}_b_${bucketId}_o_${objectId}`);
  141. }
  142. }
  143. exports.UploadService = UploadService;