simform-pocket-cli
Version:
Pocket Deploy command-line utility
183 lines • 7.91 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const axios_1 = __importDefault(require("axios"));
const build_info_parser_1 = require("build-info-parser");
const form_data_1 = __importDefault(require("form-data"));
const ApiConst_1 = __importDefault(require("./ApiConst"));
const AppConst_1 = __importDefault(require("./AppConst"));
const CommonUtils_1 = require("./CommonUtils");
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
const CommonTypes_1 = require("./types/CommonTypes");
/**
* Extract the build data from the file
* @param file - The build file
* @param fileType - The type of the build file
* @param blobData - The blob data of the build file
* @returns - The extracted build data
*/
const fileDataExtract = async (file, fileType, blobData) => {
if (fileType === CommonTypes_1.FileType.Ipa && file) {
// @ts-ignore
const parser = new build_info_parser_1.IpaParser(file);
try {
const applicationData = await parser.parse();
return {
...applicationData,
name: String(applicationData?.CFBundleDisplayName ?? AppConst_1.default.appDefaultName),
package: String(applicationData?.CFBundleIdentifier ?? AppConst_1.default.appDefaultPackage),
versionCode: Number(applicationData?.CFBundleVersion ?? AppConst_1.default.appDefaultVersionCode),
versionName: String(applicationData?.CFBundleShortVersionString ??
AppConst_1.default.appDefaultVersion),
fileType: CommonTypes_1.FileType.Ipa,
fileContentType: CommonTypes_1.FileContentType.Ipa,
appIcon: applicationData?.icon ?? '',
fileSize: blobData.size
};
}
catch (error) {
console.error(error);
}
}
else if (fileType === CommonTypes_1.FileType.Apk && file) {
const parser = new build_info_parser_1.ApkParser(file);
try {
const applicationData = await parser.parse();
if (blobData.size) {
return {
...applicationData,
name: (0, CommonUtils_1.getApkName)(applicationData?.application?.label) ??
AppConst_1.default.appDefaultName,
fileType: CommonTypes_1.FileType.Apk,
fileContentType: CommonTypes_1.FileContentType.Apk,
appIcon: applicationData?.icon ?? '',
fileSize: blobData.size
};
}
}
catch (error) {
console.error(`Error parsing APK File: ${error}`);
}
}
else {
console.error('Invalid file type');
}
};
/**
* Main function to handle the post-build process
*/
const deployApp = async (applicationId, buildPath, appToken, baseUrl, releaseNotes) => {
// Use applicationId and buildPath in your deployment logic
console.log(`Deploying Application ID: ${applicationId}`);
console.log(`Using Build Path: ${buildPath}`);
if (!applicationId) {
console.error('Application ID is missing');
process.exit(1);
}
if (!buildPath || !fs_1.default.existsSync(buildPath)) {
console.error('Build file not found:', buildPath);
process.exit(1);
}
if (!appToken) {
console.error('App token is missing');
process.exit(1);
}
const decodedToken = jsonwebtoken_1.default.decode(appToken);
const decodedApplicationId = decodedToken ? decodedToken.app : '';
if (applicationId !== decodedApplicationId) {
console.error('Application ID does not match the application token.');
process.exit(1);
}
const decodedBaseUrl = decodedToken?.baseUrl;
const currentUrl = baseUrl || decodedBaseUrl;
if (!currentUrl) {
console.error('Base URL is missing');
process.exit(1);
}
const fileType = buildPath?.split('.')?.pop() ?? CommonTypes_1.FileType.Apk;
const currentFileContentType = fileType === CommonTypes_1.FileType.Ipa ? CommonTypes_1.FileContentType.Ipa : CommonTypes_1.FileContentType.Apk;
const fileBuffer = fs_1.default.readFileSync(buildPath);
const chunkSize = AppConst_1.default.chunkSize * 1024 * 1024; // 100MB
const fileSize = fs_1.default.statSync(buildPath).size;
const totalChunks = Math.ceil(fileSize / chunkSize);
const fileStream = fs_1.default.createReadStream(buildPath, {
highWaterMark: chunkSize
});
let chunkNumber = 1;
let downloadPath = '';
const blobData = new Blob([fileBuffer], {
type: currentFileContentType
});
try {
console.log('Processing build...');
const buildInfo = await fileDataExtract(buildPath, fileType, blobData);
// Check if the build already exists
const buildExistResponse = await axios_1.default.post(`${currentUrl}/${ApiConst_1.default.buildsExist}`, {
application_id: applicationId,
version_code: buildInfo.versionCode?.toString(),
version_name: buildInfo.versionName?.toString(),
platform: buildInfo.fileType === CommonTypes_1.FileType.Ipa
? CommonTypes_1.AppPlatform.IOS
: CommonTypes_1.AppPlatform.Android
}, {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${appToken}`
}
});
if (buildExistResponse.status === 409) {
return buildExistResponse;
}
for await (const chunk of fileStream) {
const formData = new form_data_1.default();
formData.append('applicationId', applicationId);
formData.append('buildInfo', JSON.stringify(buildInfo));
formData.append('currentFileContentType', currentFileContentType);
formData.append('baseUrl', currentUrl);
formData.append('appToken', appToken);
if (releaseNotes) {
formData.append('releaseNotes', `<pre>${releaseNotes}</pre>`);
}
fileStream.on('error', err => {
console.error('Error reading the file:', err);
});
// Add current chunk
formData.append('file', chunk, {
contentType: currentFileContentType,
filename: `chunk-${chunkNumber}`
});
// Add chunk metadata
formData.append('chunkNumber', chunkNumber);
formData.append('totalChunks', totalChunks);
const response = await axios_1.default.post(`${currentUrl}/${ApiConst_1.default.deployAppToPocketDeploy}`, formData, {
headers: {
...formData.getHeaders(),
Authorization: `Bearer ${appToken}`
}
});
if (response.status === 200) {
const percentage = Math.floor((chunkNumber / totalChunks) * 100);
console.log(`Upload Progress: ${percentage}%`);
if (response?.data?.downloadPath) {
downloadPath = response?.data?.downloadPath;
}
// Increment the chunk number
chunkNumber++;
}
else {
throw new Error(`Failed to upload build`);
}
}
console.log('Build Uploaded successfully');
!!downloadPath && console.log('Download Path:', downloadPath);
return;
}
catch (error) {
console.error('Error during uploading the build:', error.response?.data ?? error);
}
};
exports.default = deployApp;
//# sourceMappingURL=deployTheApp.js.map