"use strict";
/**
 * This is the directory structure assumed for the following code
 
linkedRepoRoot
  remoteCode <---- (remoteRoot)
    metrobundles
      1
        appconfig.json
        assets
        main.jsbundle
        assetmap.json
    generated
      kflasdl12412kl239212387bfasjo128i3890230331bkjdsfasldfjaos28
        dist
        index.js
    plugins   <---- (pluginsRoot)
      plugin1 <---- (pluginFolder)
        dist
          bundle.js
        source
          widget.jsx
          component.jsx
      plugin2
      plugin3
    navigators
      navigator1
        dist
          bundle.js
        source
          index.js
      navigator2
 */
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 });
exports.compilePlugin = compilePlugin;
exports.codegenIntegrations = codegenIntegrations;
exports.compileMultiplePlugins = compileMultiplePlugins;
exports.compileNavCreator = compileNavCreator;
exports.compileMultipleNavCreators = compileMultipleNavCreators;
exports.generatAndroidBundle = generatAndroidBundle;
exports.generatIOSBundle = generatIOSBundle;
exports.generateAndroidBundle = generateAndroidBundle;
const path_1 = __importDefault(require("path"));
const webpack_1 = __importDefault(require("webpack"));
const archiver_1 = __importDefault(require("archiver"));
const promises_1 = require("node:fs/promises");
const fs_1 = require("fs");
const child_process_1 = require("child_process");
const websocket_1 = require("../websocket");
const utils_1 = require("../utils");
const webpack_config_1 = __importDefault(require("./webpack.config"));
function compilePlugin(pluginFolder) {
    return __awaiter(this, void 0, void 0, function* () {
        const config = Object.assign({}, webpack_config_1.default);
        config.entry = path_1.default.resolve(pluginFolder, `source/widget.jsx`);
        config.output.path = path_1.default.resolve(pluginFolder, 'dist');
        config.resolve.modules = [path_1.default.resolve(pluginFolder, '../../../node_modules')];
        console.log("Compiling with webpack config: ", JSON.stringify(config, null, 2));
        const compiler = (0, webpack_1.default)(config);
        return new Promise((resolve, reject) => {
            compiler.run((err, stats) => {
                var _a;
                if (err || (stats === null || stats === void 0 ? void 0 : stats.hasErrors())) {
                    console.error(err, stats);
                    if (stats) {
                        const compilationStats = stats.toJson({
                            errors: true,
                            errorsCount: true
                        });
                        const result = {
                            message: `compilation failed with ${compilationStats.errorsCount} errors`,
                            errors: (_a = compilationStats.errors) === null || _a === void 0 ? void 0 : _a.map(it => {
                                return {
                                    error: `${it.message}`,
                                    location: `${it.moduleId} at ${it.loc}`
                                };
                            })
                        };
                        reject(result);
                        (0, websocket_1.sendLog)(JSON.stringify(result, null, 2));
                    }
                    else {
                        reject(err);
                        (0, websocket_1.sendLog)("Could not compile for web: " + (err === null || err === void 0 ? void 0 : err.message) + "\n" + (err === null || err === void 0 ? void 0 : err.stack));
                    }
                }
                else {
                    (0, websocket_1.sendLog)("compilation finished!");
                    if (stats) {
                        const serializedStats = stats.toJson();
                        const result = `Compilation finished with ${serializedStats.errorsCount} errors and ${serializedStats.warningsCount} warnings`;
                        resolve(result);
                        (0, websocket_1.sendLog)(result);
                    }
                }
            });
        });
    });
}
function codegenIntegrations(appLocation, appIntegrations) {
    return __awaiter(this, void 0, void 0, function* () {
        // move package.json updates here
        const remoteCode = path_1.default.resolve(appLocation, 'remoteCode');
        const pkgJsonLocation = path_1.default.resolve(appLocation, 'package.json');
        const pkgJsonRaw = yield (0, promises_1.readFile)(pkgJsonLocation, { encoding: "utf8" });
        const pkgJson = JSON.parse(pkgJsonRaw);
        for (let integration of appIntegrations) {
            if (pkgJson.dependencies[integration.integrationCode] !== integration.packageLocation) {
                pkgJson.dependencies[integration.integrationCode] = integration.packageLocation;
            }
            const packageName = integration.integrationCode;
            const camelCasePackageName = (0, utils_1.toCamelCase)(packageName);
            try {
                yield (0, promises_1.mkdir)(path_1.default.resolve(remoteCode, 'plugins', packageName, 'source'), { recursive: true });
            }
            catch (err) {
                if ((err === null || err === void 0 ? void 0 : err.code) !== 'EEXIST') {
                    console.error("Could not create directory for integration", err);
                }
            }
            const pluginsLinkingFile = path_1.default.resolve(remoteCode, 'plugins', packageName, 'source/widget.jsx');
            yield (0, promises_1.writeFile)(pluginsLinkingFile, `import ${camelCasePackageName} from "${packageName}";
export default ${camelCasePackageName};\n`);
            // write the file
            // have a function in projectSetup to re-run the codegen for linking and run it
        }
        yield (0, promises_1.writeFile)(pkgJsonLocation, JSON.stringify(pkgJson, null, 2));
    });
}
function metroCodegenPlugins(remoteCode, pluginNames) {
    return __awaiter(this, void 0, void 0, function* () {
        let contents = `export function initPlugins() {
return [
`;
        for (let name of pluginNames) {
            const camelCasePackageName = (0, utils_1.toCamelCase)(name);
            contents = `import ${camelCasePackageName} from "./plugins/${name}/source/widget";\n` + contents;
            contents += `    ${camelCasePackageName},\n`;
        }
        contents = "// This file is generated. Do not edit.\n" + contents + "  ];\n}";
        const iosRemoteEntryPath = path_1.default.resolve(remoteCode, 'index.js');
        yield (0, promises_1.writeFile)(iosRemoteEntryPath, contents);
        (0, websocket_1.sendLog)(`Code generation finished for ios. Output written to ${iosRemoteEntryPath}`);
    });
}
function compileMultiplePlugins(remoteCode, pluginNames, compiledDirName) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const generatedPath = path_1.default.resolve(remoteCode, 'generated', compiledDirName);
            const generatedEntryPath = path_1.default.resolve(generatedPath, 'index.js');
            const distPath = path_1.default.resolve(generatedPath, 'dist');
            const pluginsRoot = path_1.default.resolve(remoteCode, 'plugins');
            yield (0, promises_1.mkdir)(distPath, { recursive: true });
            // Generate for web
            (0, websocket_1.sendLog)("Generating import file for plugins " + pluginNames.join(','));
            let contents = `\n\nexport default [\n`;
            for (let name of pluginNames) {
                contents = `import ${(0, utils_1.toCamelCase)(name)} from "${path_1.default.resolve(pluginsRoot, name, 'source/widget')}";\n` + contents;
                contents += `  ${(0, utils_1.toCamelCase)(name)},\n`;
            }
            contents += "]";
            yield (0, promises_1.writeFile)(generatedEntryPath, contents);
            (0, websocket_1.sendLog)(`Code generation finished. Output written to ${generatedEntryPath}`);
            yield metroCodegenPlugins(remoteCode, pluginNames);
            const config = Object.assign({}, webpack_config_1.default);
            config.entry = generatedEntryPath;
            config.output.path = distPath;
            config.resolve.modules = [path_1.default.resolve(remoteCode, '../node_modules')];
            console.log("Compiling with webpack config: ", JSON.stringify(config, null, 2));
            const compiler = (0, webpack_1.default)(config);
            return new Promise((resolve, reject) => {
                compiler.run((err, stats) => {
                    var _a;
                    if (err || (stats === null || stats === void 0 ? void 0 : stats.hasErrors())) {
                        (0, websocket_1.sendLog)(`compilation failed: ${err === null || err === void 0 ? void 0 : err.message}`);
                        if (stats) {
                            const compilationStats = stats.toJson({
                                errors: true,
                                errorsCount: true
                            });
                            (0, websocket_1.sendLog)(`compilation failed with ${compilationStats.errorsCount} errors`);
                            const result = {
                                message: `compilation failed with ${compilationStats.errorsCount} errors`,
                                errors: (_a = compilationStats.errors) === null || _a === void 0 ? void 0 : _a.map(it => {
                                    (0, websocket_1.sendLog)('------------------------------------------------------------------');
                                    (0, websocket_1.sendLog)(it.message.replace(/\x1B\[[0-9;]*m/g, ''));
                                    (0, websocket_1.sendLog)(`location: \n${it.moduleId} at ${it.loc}`);
                                    return {
                                        error: it.message.replace(/\x1B\[[0-9;]*m/g, ''),
                                        location: `${it.moduleId} at ${it.loc}`
                                    };
                                })
                            };
                            reject(result);
                        }
                        else {
                            const result = { message: (err === null || err === void 0 ? void 0 : err.toString()) || "error is null" };
                            reject(result);
                            (0, websocket_1.sendLog)(JSON.stringify(result, null, 2));
                        }
                    }
                    else {
                        console.log("compilation finished! ", stats === null || stats === void 0 ? void 0 : stats.compilation.assets);
                        if (stats) {
                            const serializedStats = stats.toJson();
                            const result = {
                                message: `Compilation finished with ${serializedStats.errorsCount} errors and ${serializedStats.warningsCount} warnings`
                            };
                            resolve(result);
                            (0, websocket_1.sendLog)(JSON.stringify(result, null, 2));
                        }
                        else {
                            resolve({
                                message: `Compilation completed but no stats were generated`
                            });
                            (0, websocket_1.sendLog)(`Compilation completed but no stats were generated`);
                        }
                    }
                });
            });
        }
        catch (err) {
            (0, websocket_1.sendLog)(`compilation failed due to ${err.toString()}`);
            return Promise.reject({
                message: `compilation failed due to ${err.toString()}`
            });
        }
    });
}
function compileNavCreator(appid, name) {
    return __awaiter(this, void 0, void 0, function* () {
        const config = Object.assign({}, webpack_config_1.default);
        config.entry = path_1.default.resolve(__dirname, `../workspace/${appid}/navigators/${name}/index.jsx`);
        config.output.path = path_1.default.resolve(__dirname, `../workspace/${appid}/navigators/${name}/dist`);
        const compiler = (0, webpack_1.default)(config);
        return new Promise((resolve, reject) => {
            compiler.run((err, stats) => {
                var _a;
                if (err || (stats === null || stats === void 0 ? void 0 : stats.hasErrors())) {
                    console.error(err, stats);
                    if (stats) {
                        const compilationStats = stats.toJson({
                            errors: true,
                            errorsCount: true
                        });
                        reject({
                            message: `compilation failed with ${compilationStats.errorsCount} errors`,
                            errors: (_a = compilationStats.errors) === null || _a === void 0 ? void 0 : _a.map(it => {
                                return {
                                    error: `${it.message}`,
                                    location: `${it.moduleId} at ${it.loc}`
                                };
                            })
                        });
                    }
                    else {
                        reject(err);
                    }
                }
                else {
                    console.log("compilation finished!");
                    if (stats) {
                        const serializedStats = stats.toJson();
                        resolve(`Compilation finished with ${serializedStats.errorsCount} errors and ${serializedStats.warningsCount} warnings`);
                    }
                }
            });
        });
    });
}
function metroCodegenNavs(remoteCode, navNames) {
    return __awaiter(this, void 0, void 0, function* () {
        const navsRoot = path_1.default.resolve(remoteCode, 'navigators');
        // Generate for phone
        let contents = `import {registerCreator} from 'apptile-core';
export const navs = [
`;
        for (let name of navNames) {
            const camelCasePackageName = (0, utils_1.toCamelCase)(name);
            contents = `import ${camelCasePackageName} from "${path_1.default.resolve(navsRoot, name, `source/index`)}";\n` + contents;
            contents += `  {creator: ${camelCasePackageName}, name: "${name}"},\n`;
        }
        contents += `];\n
export function initNavs() {
  for (let nav of navs) {
    registerCreator(nav.name, nav.creator);
  }
}
  `;
        contents = `// This file is generated. Do not edit.\n` + contents;
        const iosRemoteNavEntry = path_1.default.resolve(remoteCode, 'indexNav.js');
        yield (0, promises_1.writeFile)(iosRemoteNavEntry, contents);
        (0, websocket_1.sendLog)(`Codegeneration finished for mobile navigators\n`);
    });
}
function compileMultipleNavCreators(repoPath, navNames, compiledDirName) {
    return __awaiter(this, void 0, void 0, function* () {
        const remoteCode = path_1.default.resolve(repoPath, 'remoteCode');
        try {
            const generatedPath = path_1.default.resolve(remoteCode, 'generated', compiledDirName);
            const generatedEntryPath = path_1.default.resolve(generatedPath, 'index.js');
            const distPath = path_1.default.resolve(generatedPath, 'dist');
            const navsRoot = path_1.default.resolve(remoteCode, 'navigators');
            yield (0, promises_1.mkdir)(distPath, { recursive: true });
            // Generate for web
            (0, websocket_1.sendLog)("Generating imports file for navigators" + navNames.join(','));
            let contents = `\n\nexport default [\n`;
            for (let name of navNames) {
                contents = `import ${name} from "${path_1.default.resolve(navsRoot, name, 'source')}";\n` + contents;
                contents += `  { creator: ${name}, name: "${name}" },\n`;
            }
            contents += "]";
            yield (0, promises_1.writeFile)(generatedEntryPath, contents);
            (0, websocket_1.sendLog)(`Code generation finished. Output written to ${generatedEntryPath}`);
            metroCodegenNavs(remoteCode, navNames);
            const config = Object.assign({}, webpack_config_1.default);
            config.entry = generatedEntryPath;
            config.output.path = distPath;
            config.resolve.modules = [path_1.default.resolve(remoteCode, '../node_modules')];
            console.log("Compiling with webpack config: ", JSON.stringify(config, null, 2));
            const compiler = (0, webpack_1.default)(config);
            return new Promise((resolve, reject) => {
                compiler.run((err, stats) => {
                    var _a;
                    if (err || (stats === null || stats === void 0 ? void 0 : stats.hasErrors())) {
                        console.error(err, stats);
                        if (stats) {
                            const compilationStats = stats.toJson({
                                errors: true,
                                errorsCount: true
                            });
                            reject({
                                message: `compilation failed with ${compilationStats.errorsCount} errors`,
                                errors: (_a = compilationStats.errors) === null || _a === void 0 ? void 0 : _a.map(it => {
                                    return {
                                        error: `${it.message}`,
                                        location: `${it.moduleId} at ${it.loc}`
                                    };
                                })
                            });
                        }
                        else {
                            reject({ message: (err === null || err === void 0 ? void 0 : err.toString()) || "error is null" });
                        }
                    }
                    else {
                        console.log("compilation finished!");
                        if (stats) {
                            const serializedStats = stats.toJson();
                            resolve({
                                message: `Compilation finished with ${serializedStats.errorsCount} errors and ${serializedStats.warningsCount} warnings`
                            });
                        }
                        else {
                            resolve({
                                message: `Compilation completed but no stats were generated`
                            });
                        }
                    }
                });
            });
        }
        catch (err) {
            return Promise.reject({
                message: `compilation failed due to ${err.toString()}`
            });
        }
    });
}
function generatAndroidBundle(appRoot) {
    return __awaiter(this, void 0, void 0, function* () {
        const remoteCode = path_1.default.resolve(appRoot, 'remoteCode');
        // get list of plugins and navs
        const pluginsDir = path_1.default.resolve(remoteCode, 'plugins');
        const pluginEntries = yield (0, promises_1.readdir)(pluginsDir, { withFileTypes: true });
        const plugins = pluginEntries.filter(it => it.isDirectory()).map(it => it.name);
        const navDir = path_1.default.resolve(remoteCode, 'navigators');
        const navEntries = yield (0, promises_1.readdir)(navDir, { withFileTypes: true });
        const navs = navEntries.filter(it => it.isDirectory()).map(it => it.name);
        // do metro codegen for plugins and navs
        yield metroCodegenPlugins(remoteCode, plugins);
        yield metroCodegenNavs(remoteCode, navs);
        // execute metro bundler and send logs
        const command = "node_modules/.bin/react-native bundle --entry-file ./index.js --platform android --dev false --minify true --bundle-output ./android/index.android.bundle --assets-dest ./android/bundleassets";
        (0, websocket_1.sendLog)("Start bundling for phone");
        yield new Promise((resolve, reject) => {
            (0, child_process_1.exec)(command, {
                cwd: path_1.default.resolve(appRoot)
            }, (err, stdout, stderr) => {
                if (err) {
                    (0, websocket_1.sendLog)("Failed to generate build! " + err.message);
                    console.error(err);
                    reject(err);
                }
                else {
                    (0, websocket_1.sendLog)(stdout);
                    (0, websocket_1.sendLog)(stderr);
                    resolve({});
                }
            });
        });
        // zip assets
        const timestamp = Date.now();
        const generatedPath = path_1.default.resolve(remoteCode, `generated/bundles/android/${timestamp}`);
        yield (0, promises_1.mkdir)(generatedPath, { recursive: true });
        // put built files into generated folder so that it can be served through cli
        // await cp(
        //   path.resolve(appRoot, 'ios/main.jsbundle'), 
        //   path.resolve(generatedPath, 'main.jsbundle')
        // );
        yield new Promise((resolve, reject) => {
            const bundleDestination = path_1.default.resolve(generatedPath, 'bundle.zip');
            const writeStream = (0, fs_1.createWriteStream)(bundleDestination);
            writeStream.on('close', () => {
                (0, websocket_1.sendLog)(`zipping finished. Bundle is at ${bundleDestination}`);
                resolve({});
            });
            writeStream.on('error', (err) => {
                (0, websocket_1.sendLog)('Zipping failed ' + err.message);
                reject(err);
            });
            const archive = (0, archiver_1.default)('zip', { zlib: { level: 9 } });
            archive.on('warning', wrn => {
                (0, websocket_1.sendLog)('archiver warning: ' + wrn.message);
                console.warn('archiver warning: ', wrn);
            });
            archive.on('error', err => {
                if (err) {
                    (0, websocket_1.sendLog)('archiver error: ' + err.message);
                    console.error("Failure in archiver ", err);
                }
            });
            archive.pipe(writeStream);
            archive.file(path_1.default.resolve(appRoot, 'android/index.android.bundle'), { name: 'index.android.bundle' });
            archive.directory(path_1.default.resolve(appRoot, 'android/bundleassets'), false);
            archive.finalize();
        });
    });
}
function generatIOSBundle(appRoot) {
    return __awaiter(this, void 0, void 0, function* () {
        const remoteCode = path_1.default.resolve(appRoot, 'remoteCode');
        // get list of plugins and navs
        const pluginsDir = path_1.default.resolve(remoteCode, 'plugins');
        const pluginEntries = yield (0, promises_1.readdir)(pluginsDir, { withFileTypes: true });
        const plugins = pluginEntries.filter(it => it.isDirectory()).map(it => it.name);
        const navDir = path_1.default.resolve(remoteCode, 'navigators');
        const navEntries = yield (0, promises_1.readdir)(navDir, { withFileTypes: true });
        const navs = navEntries.filter(it => it.isDirectory()).map(it => it.name);
        // do metro codegen for plugins and navs
        yield metroCodegenPlugins(remoteCode, plugins);
        yield metroCodegenNavs(remoteCode, navs);
        // execute metro bundler and send logs
        const command = "node_modules/.bin/react-native bundle --entry-file ./index.js --platform ios --dev false --minify true --bundle-output ./ios/main.jsbundle --assets-dest ./ios/bundleassets";
        (0, websocket_1.sendLog)("Start bundling for phone");
        yield new Promise((resolve, reject) => {
            (0, child_process_1.exec)(command, {
                cwd: path_1.default.resolve(appRoot)
            }, (err, stdout, stderr) => {
                if (err) {
                    (0, websocket_1.sendLog)("Failed to generate build! " + err.message);
                    console.error(err);
                    reject(err);
                }
                else {
                    (0, websocket_1.sendLog)(stdout);
                    (0, websocket_1.sendLog)(stderr);
                    resolve({});
                }
            });
        });
        // zip assets
        const timestamp = Date.now();
        const generatedPath = path_1.default.resolve(remoteCode, `generated/bundles/ios/${timestamp}`);
        yield (0, promises_1.mkdir)(generatedPath, { recursive: true });
        // put built files into generated folder so that it can be served through cli
        // await cp(
        //   path.resolve(appRoot, 'ios/main.jsbundle'), 
        //   path.resolve(generatedPath, 'main.jsbundle')
        // );
        yield new Promise((resolve, reject) => {
            const bundleDestination = path_1.default.resolve(generatedPath, 'bundle.zip');
            const writeStream = (0, fs_1.createWriteStream)(bundleDestination);
            writeStream.on('close', () => {
                (0, websocket_1.sendLog)(`zipping finished. Bundle is at ${bundleDestination}`);
                resolve({});
            });
            writeStream.on('error', (err) => {
                (0, websocket_1.sendLog)('Zipping failed ' + err.message);
                reject(err);
            });
            const archive = (0, archiver_1.default)('zip', { zlib: { level: 9 } });
            archive.on('warning', wrn => {
                (0, websocket_1.sendLog)('archiver warning: ' + wrn.message);
                console.warn('archiver warning: ', wrn);
            });
            archive.on('error', err => {
                if (err) {
                    (0, websocket_1.sendLog)('archiver error: ' + err.message);
                    console.error("Failure in archiver ", err);
                }
            });
            archive.pipe(writeStream);
            archive.file(path_1.default.resolve(appRoot, 'ios/main.jsbundle'), { name: 'main.jsbundle' });
            archive.directory(path_1.default.resolve(appRoot, 'ios/bundleassets'), false);
            archive.finalize();
        });
    });
}
function generateAndroidBundle(appRoot) {
    return __awaiter(this, void 0, void 0, function* () {
        const remoteCode = path_1.default.resolve(appRoot, 'remoteCode');
        // get list of plugins and navs
        const pluginsDir = path_1.default.resolve(remoteCode, 'plugins');
        const pluginEntries = yield (0, promises_1.readdir)(pluginsDir, { withFileTypes: true });
        const plugins = pluginEntries.filter(it => it.isDirectory()).map(it => it.name);
        const navDir = path_1.default.resolve(remoteCode, 'navigators');
        const navEntries = yield (0, promises_1.readdir)(navDir, { withFileTypes: true });
        const navs = navEntries.filter(it => it.isDirectory()).map(it => it.name);
        // do metro codegen for plugins and navs
        yield metroCodegenPlugins(remoteCode, plugins);
        yield metroCodegenNavs(remoteCode, navs);
        // execute metro bundler and send logs
        const command = "node_modules/.bin/react-native bundle --entry-file ./index.js --platform android --dev false --minify true --bundle-output ./android/app/src/main/assets/index.android.bundle --assets-dest ./android/app/src/main/assets/assets";
        (0, websocket_1.sendLog)("Start bundling for phone");
        yield new Promise((resolve, reject) => {
            (0, child_process_1.exec)(command, {
                cwd: path_1.default.resolve(appRoot)
            }, (err, stdout, stderr) => {
                if (err) {
                    (0, websocket_1.sendLog)("Failed to generate build! " + err.message);
                    console.error(err);
                    reject(err);
                }
                else {
                    (0, websocket_1.sendLog)(stdout);
                    (0, websocket_1.sendLog)(stderr);
                    resolve({});
                }
            });
        });
        // zip assets
        const timestamp = Date.now();
        const generatedPath = path_1.default.resolve(remoteCode, `generated/bundles/android/${timestamp}`);
        yield (0, promises_1.mkdir)(generatedPath, { recursive: true });
        // put built files into generated folder so that it can be served through cli
        // await cp(
        //   path.resolve(appRoot, 'ios/main.jsbundle'), 
        //   path.resolve(generatedPath, 'main.jsbundle')
        // );
        yield new Promise((resolve, reject) => {
            const bundleDestination = path_1.default.resolve(generatedPath, 'bundle.zip');
            const writeStream = (0, fs_1.createWriteStream)(bundleDestination);
            writeStream.on('close', () => {
                (0, websocket_1.sendLog)(`zipping finished. Bundle is at ${bundleDestination}`);
                resolve({});
            });
            writeStream.on('error', (err) => {
                (0, websocket_1.sendLog)('Zipping failed ' + err.message);
                reject(err);
            });
            const archive = (0, archiver_1.default)('zip', { zlib: { level: 9 } });
            archive.on('warning', wrn => {
                (0, websocket_1.sendLog)('archiver warning: ' + wrn.message);
                console.warn('archiver warning: ', wrn);
            });
            archive.on('error', err => {
                if (err) {
                    (0, websocket_1.sendLog)('archiver error: ' + err.message);
                    console.error("Failure in archiver ", err);
                }
            });
            archive.pipe(writeStream);
            archive.file(path_1.default.resolve(appRoot, 'android/app/src/main/assets/index.android.bundle'), { name: 'index.android.bundle' });
            archive.directory(path_1.default.resolve(appRoot, 'android/app/src/main/assets/assets'), false);
            archive.finalize();
        });
    });
}
