@capawesome/cli
Version:
The Capawesome Cloud Command Line Interface (CLI) to manage Live Updates and more.
156 lines (155 loc) • 7.3 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
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) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const form_data_1 = __importDefault(require("form-data"));
const config_1 = require("../config");
const http_client_1 = __importDefault(require("../utils/http-client"));
const authorization_service_1 = __importDefault(require("./authorization-service"));
class AppBundleFilesServiceImpl {
constructor(httpClient) {
this.httpClient = httpClient;
}
create(dto) {
return __awaiter(this, void 0, void 0, function* () {
const sizeInBytes = dto.buffer.byteLength;
const useMultipartUpload = sizeInBytes >= 100 * 1024 * 1024; // 100 MB
const formData = new form_data_1.default();
formData.append('checksum', dto.checksum);
if (!useMultipartUpload) {
formData.append('file', dto.buffer, { filename: dto.name });
}
if (dto.href) {
formData.append('href', dto.href);
}
formData.append('mimeType', dto.mimeType);
formData.append('name', dto.name);
if (dto.signature) {
formData.append('signature', dto.signature);
}
formData.append('sizeInBytes', sizeInBytes.toString());
const response = yield this.httpClient.post(`/v1/apps/${dto.appId}/bundles/${dto.appBundleId}/files`, formData, {
headers: Object.assign({ Authorization: `Bearer ${authorization_service_1.default.getCurrentAuthorizationToken()}` }, formData.getHeaders()),
});
if (useMultipartUpload) {
yield this.upload({
appBundleFileId: response.data.id,
appBundleId: dto.appBundleId,
appId: dto.appId,
buffer: dto.buffer,
name: dto.name,
checksum: dto.checksum,
});
}
return response.data;
});
}
completeUpload(dto) {
return __awaiter(this, void 0, void 0, function* () {
return this.httpClient
.post(`/v1/apps/${dto.appId}/bundles/${dto.appBundleId}/files/${dto.appBundleFileId}/upload?action=mpu-complete&uploadId=${dto.uploadId}`, {
parts: dto.parts,
}, {
headers: {
Authorization: `Bearer ${authorization_service_1.default.getCurrentAuthorizationToken()}`,
},
})
.then((response) => response.data);
});
}
createUpload(dto) {
return __awaiter(this, void 0, void 0, function* () {
const response = yield this.httpClient.post(`/v1/apps/${dto.appId}/bundles/${dto.appBundleId}/files/${dto.appBundleFileId}/upload?action=mpu-create`, {}, {
headers: {
Authorization: `Bearer ${authorization_service_1.default.getCurrentAuthorizationToken()}`,
},
});
return response.data;
});
}
createUploadPart(dto) {
return __awaiter(this, void 0, void 0, function* () {
const formData = new form_data_1.default();
formData.append('blob', dto.buffer, { filename: dto.name });
formData.append('partNumber', dto.partNumber.toString());
return this.httpClient
.put(`/v1/apps/${dto.appId}/bundles/${dto.appBundleId}/files/${dto.appBundleFileId}/upload?action=mpu-uploadpart&uploadId=${dto.uploadId}`, formData, {
headers: Object.assign({ Authorization: `Bearer ${authorization_service_1.default.getCurrentAuthorizationToken()}` }, formData.getHeaders()),
})
.then((response) => response.data);
});
}
createUploadParts(dto) {
return __awaiter(this, void 0, void 0, function* () {
const uploadedParts = [];
const partSize = 10 * 1024 * 1024; // 10 MB. 5 MB is the minimum part size except for the last part.
const totalParts = Math.ceil(dto.buffer.byteLength / partSize);
let partNumber = 0;
const uploadNextPart = () => __awaiter(this, void 0, void 0, function* () {
if (partNumber >= totalParts) {
return;
}
partNumber++;
const start = (partNumber - 1) * partSize;
const end = Math.min(start + partSize, dto.buffer.byteLength);
const partBuffer = dto.buffer.subarray(start, end);
const uploadedPart = yield this.createUploadPart({
appBundleFileId: dto.appBundleFileId,
appBundleId: dto.appBundleId,
appId: dto.appId,
buffer: partBuffer,
name: dto.name,
partNumber,
uploadId: dto.uploadId,
});
uploadedParts.push(uploadedPart);
yield uploadNextPart();
});
const uploadPartPromises = Array.from({ length: config_1.MAX_CONCURRENT_UPLOADS });
for (let i = 0; i < config_1.MAX_CONCURRENT_UPLOADS; i++) {
uploadPartPromises[i] = uploadNextPart();
}
yield Promise.all(uploadPartPromises);
return uploadedParts;
});
}
upload(dto) {
return __awaiter(this, void 0, void 0, function* () {
// 1. Create a multipart upload
const { uploadId } = yield this.createUpload({
appBundleFileId: dto.appBundleFileId,
appBundleId: dto.appBundleId,
appId: dto.appId,
});
// 2. Upload the file in parts
const parts = yield this.createUploadParts({
appBundleFileId: dto.appBundleFileId,
appBundleId: dto.appBundleId,
appId: dto.appId,
buffer: dto.buffer,
name: dto.name,
uploadId,
});
// 3. Complete the upload
yield this.completeUpload({
appBundleFileId: dto.appBundleFileId,
appBundleId: dto.appBundleId,
appId: dto.appId,
parts,
uploadId,
});
});
}
}
const appBundleFilesService = new AppBundleFilesServiceImpl(http_client_1.default);
exports.default = appBundleFilesService;