meteor-desktop
Version:
Build a Meteor's desktop client with hot code push.
876 lines (695 loc) • 110 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _runtime = _interopRequireDefault(require("regenerator-runtime/runtime"));
var _asar = _interopRequireDefault(require("asar"));
var _assignIn = _interopRequireDefault(require("lodash/assignIn"));
var _lodash = _interopRequireDefault(require("lodash"));
var _installLocal = require("install-local");
var _core = require("@babel/core");
var _crypto = _interopRequireDefault(require("crypto"));
var _del = _interopRequireDefault(require("del"));
var _presetEnv = _interopRequireDefault(require("@babel/preset-env"));
var _fs = _interopRequireDefault(require("fs"));
var _path = _interopRequireDefault(require("path"));
var _shelljs = _interopRequireDefault(require("shelljs"));
var _semver = _interopRequireDefault(require("semver"));
var _terser = _interopRequireDefault(require("terser"));
var _log = _interopRequireDefault(require("./log"));
var _electronAppScaffold = _interopRequireDefault(require("./electronAppScaffold"));
var _dependenciesManager = _interopRequireDefault(require("./dependenciesManager"));
var _binaryModulesDetector = _interopRequireDefault(require("./binaryModulesDetector"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// eslint-disable-next-line no-unused-vars
_shelljs.default.config.fatal = true;
/**
* Represents the .desktop dir scaffold.
* @class
*/
class ElectronApp {
/**
* @param {MeteorDesktop} $ - context
* @constructor
*/
constructor($) {
this.log = new _log.default('electronApp');
this.scaffold = new _electronAppScaffold.default($);
this.depsManager = new _dependenciesManager.default($, this.scaffold.getDefaultPackageJson().dependencies);
this.$ = $;
this.meteorApp = this.$.meteorApp;
this.packageJson = null;
this.version = null;
this.compatibilityVersion = null;
this.deprectatedPlugins = ['meteor-desktop-localstorage'];
}
/**
* Makes an app.asar from the skeleton app.
* @property {Array} excludeFromDel - list of paths to exclude from deleting
* @returns {Promise}
*/
packSkeletonToAsar(excludeFromDel = []) {
this.log.info('packing skeleton app and node_modules to asar archive');
return new Promise(resolve => {
const extract = this.getModulesToExtract(); // We want to pack skeleton app and node_modules together, so we need to temporarily
// move node_modules to app dir.
this.log.debug('moving node_modules to app dir');
_fs.default.renameSync(this.$.env.paths.electronApp.nodeModules, _path.default.join(this.$.env.paths.electronApp.appRoot, 'node_modules'));
let extracted = false;
extracted = this.extractModules(extract);
this.log.debug('packing');
_asar.default.createPackage(this.$.env.paths.electronApp.appRoot, this.$.env.paths.electronApp.appAsar, () => {
// Lets move the node_modules back.
this.log.debug('moving node_modules back from app dir');
_shelljs.default.mv(_path.default.join(this.$.env.paths.electronApp.appRoot, 'node_modules'), this.$.env.paths.electronApp.nodeModules);
if (extracted) {
// We need to create a full node modules back. In other words we want
// the extracted modules back.
extract.forEach(module => _shelljs.default.cp('-rf', _path.default.join(this.$.env.paths.electronApp.extractedNodeModules, module), _path.default.join(this.$.env.paths.electronApp.nodeModules, module))); // Get the .bin back.
if (this.$.utils.exists(this.$.env.paths.electronApp.extractedNodeModulesBin)) {
_shelljs.default.cp(_path.default.join(this.$.env.paths.electronApp.extractedNodeModulesBin, '*'), _path.default.join(this.$.env.paths.electronApp.nodeModules, '.bin'));
}
}
this.log.debug('deleting source files');
const exclude = [this.$.env.paths.electronApp.nodeModules].concat([this.$.env.paths.electronApp.appAsar, this.$.env.paths.electronApp.packageJson], excludeFromDel);
_del.default.sync([`${this.$.env.paths.electronApp.root}${_path.default.sep}*`].concat(exclude.map(pathToExclude => `!${pathToExclude}`)), {
force: true
});
resolve();
});
});
}
/**
* Moves specified node modules to a separate directory.
* @param {Array} extract
* @returns {boolean}
*/
extractModules(extract) {
const ext = ['.js', '.bat', '.sh', '.cmd', ''];
if (extract.length > 0) {
if (this.$.utils.exists(this.$.env.paths.electronApp.extractedNodeModules)) {
_shelljs.default.rm('-rf', this.$.env.paths.electronApp.extractedNodeModules);
}
_fs.default.mkdirSync(this.$.env.paths.electronApp.extractedNodeModules);
_fs.default.mkdirSync(this.$.env.paths.electronApp.extractedNodeModulesBin);
extract.forEach(module => {
_fs.default.renameSync(_path.default.join(this.$.env.paths.electronApp.appRoot, 'node_modules', module), _path.default.join(this.$.env.paths.electronApp.extractedNodeModules, module)); // Move bins.
this.extractBin(module, ext);
});
return true;
}
return false;
}
/**
* Extracts the bin files associated with a certain node modules.
*
* @param module
* @param ext
*/
extractBin(module, ext) {
let packageJson;
try {
packageJson = JSON.parse(_fs.default.readFileSync(_path.default.join(this.$.env.paths.electronApp.extractedNodeModules, module, 'package.json'), 'utf8'));
} catch (e) {
packageJson = {};
}
const bins = 'bin' in packageJson && typeof packageJson.bin === 'object' ? Object.keys(packageJson.bin) : [];
if (bins.length > 0) {
bins.forEach(bin => {
ext.forEach(extension => {
const binFilePath = _path.default.join(this.$.env.paths.electronApp.appRoot, 'node_modules', '.bin', `${bin}${extension}`);
if (this.$.utils.exists(binFilePath) || this.$.utils.symlinkExists(binFilePath)) {
_fs.default.renameSync(binFilePath, _path.default.join(this.$.env.paths.electronApp.extractedNodeModulesBin, `${bin}${extension}`));
}
});
});
}
}
/**
* Merges the `extract` field with automatically detected modules.
*/
getModulesToExtract() {
const binaryModulesDetector = new _binaryModulesDetector.default(this.$.env.paths.electronApp.nodeModules);
const toBeExtracted = binaryModulesDetector.detect();
let {
extract
} = this.$.desktop.getSettings();
if (!Array.isArray(extract)) {
extract = [];
}
const merge = {};
toBeExtracted.concat(extract).forEach(module => {
merge[module] = true;
});
extract = Object.keys(merge);
if (extract.length > 0) {
this.log.verbose(`resultant modules to extract list is: ${extract.join(', ')}`);
}
return extract;
}
/**
* Calculates a md5 from all dependencies.
*/
calculateCompatibilityVersion() {
this.log.verbose('calculating compatibility version');
const settings = this.$.desktop.getSettings();
if ('desktopHCPCompatibilityVersion' in settings) {
this.compatibilityVersion = `${settings.desktopHCPCompatibilityVersion}`;
this.log.warn(`compatibility version overridden to ${this.compatibilityVersion}`);
return;
}
const md5 = _crypto.default.createHash('md5');
let dependencies = this.depsManager.getDependencies();
const dependenciesSorted = Object.keys(dependencies).sort();
dependencies = dependenciesSorted.map(dependency => `${dependency}:${dependencies[dependency]}`);
const mainCompatibilityVersion = this.$.getVersion().split('.');
this.log.debug('meteor-desktop compatibility version is ', `${mainCompatibilityVersion[0]}`);
dependencies.push(`meteor-desktop:${mainCompatibilityVersion[0]}`);
const desktopCompatibilityVersion = settings.version.split('.')[0];
this.log.debug('.desktop compatibility version is ', desktopCompatibilityVersion);
dependencies.push(`desktop-app:${desktopCompatibilityVersion}`);
if (process.env.METEOR_DESKTOP_DEBUG_DESKTOP_COMPATIBILITY_VERSION || process.env.METEOR_DESKTOP_DEBUG) {
this.log.debug(`compatibility version calculated from ${JSON.stringify(dependencies)}`);
}
md5.update(JSON.stringify(dependencies));
this.compatibilityVersion = md5.digest('hex');
}
async init() {
try {
await this.$.electron.init();
await this.$.electronBuilder.init();
} catch (e) {
this.log.warn('error occurred while initialising electron and electron-builder integration', e);
process.exit(1);
}
}
/**
* Runs all necessary tasks to build the desktopified app.
*/
async build(run = false) {
// TODO: refactor to a task runner
this.log.info('scaffolding');
if (!this.$.desktop.check()) {
if (!this.$.env.options.scaffold) {
this.log.error('seems that you do not have a .desktop dir in your project or it is' + ' corrupted. Run \'npm run desktop -- init\' to get a new one.'); // Do not fail, so that npm will not print his error stuff to console.
process.exit(0);
} else {
this.$.desktop.scaffold();
this.$.meteorApp.updateGitIgnore();
}
}
await this.init();
try {
this.$.meteorApp.updateGitIgnore();
} catch (e) {
this.log.warn(`error occurred while adding ${this.$.env.paths.electronApp.rootName}` + 'to .gitignore: ', e);
}
try {
await this.$.meteorApp.removeDeprecatedPackages();
} catch (e) {
this.log.error('error while removing deprecated packages: ', e);
process.exit(1);
}
try {
await this.$.meteorApp.ensureDesktopHCPPackages();
} catch (e) {
this.log.error('error while checking for required packages: ', e);
process.exit(1);
}
try {
await this.scaffold.make();
} catch (e) {
this.log.error('error while scaffolding: ', e);
process.exit(1);
}
try {
const fileName = '.npmrc';
const dirName = '.meteor/desktop-build';
if (_fs.default.existsSync(dirName) && _fs.default.existsSync(fileName)) {
_fs.default.copyFileSync(fileName, `${dirName}/${fileName}`);
}
} catch (e) {
this.log.warn('error while copying .npmrc', e);
}
try {
await this.exposeElectronModules();
} catch (e) {
this.log.error('error while exposing electron modules: ', e);
process.exit(1);
}
try {
this.updatePackageJsonFields();
} catch (e) {
this.log.error('error while updating package.json: ', e);
}
try {
this.updateDependenciesList();
} catch (e) {
this.log.error('error while merging dependencies list: ', e);
}
try {
this.calculateCompatibilityVersion();
} catch (e) {
this.log.error('error while calculating compatibility version: ', e);
process.exit(1);
}
try {
await this.handleTemporaryNodeModules();
} catch (e) {
this.log.error('error occurred while handling temporary node_modules: ', e);
process.exit(1);
}
let nodeModulesRemoved;
try {
nodeModulesRemoved = await this.handleStateOfNodeModules();
} catch (e) {
this.log.error('error occurred while clearing node_modules: ', e);
process.exit(1);
}
try {
await this.rebuildDeps(true);
} catch (e) {
this.log.error('error occurred while installing node_modules: ', e);
process.exit(1);
}
if (!nodeModulesRemoved) {
try {
await this.rebuildDeps();
} catch (e) {
this.log.error('error occurred while rebuilding native node modules: ', e);
process.exit(1);
}
}
try {
await this.linkNpmPackages();
} catch (e) {
this.log.error(`linking packages failed: ${e}`);
process.exit(1);
}
try {
await this.installLocalNodeModules();
} catch (e) {
this.log.error('error occurred while installing local node modules: ', e);
process.exit(1);
}
try {
await this.ensureMeteorDependencies();
} catch (e) {
this.log.error('error occurred while ensuring meteor dependencies are installed: ', e);
process.exit(1);
}
if (this.$.env.isProductionBuild()) {
try {
await this.packSkeletonToAsar();
} catch (e) {
this.log.error('error while packing skeleton to asar: ', e);
process.exit(1);
}
} // TODO: find a way to avoid copying .desktop to a temp location
try {
this.copyDesktopToDesktopTemp();
} catch (e) {
this.log.error('error while copying .desktop to a temporary location: ', e);
process.exit(1);
}
try {
await this.updateSettingsJsonFields();
} catch (e) {
this.log.error('error while updating settings.json: ', e);
process.exit(1);
}
try {
await this.excludeFilesFromArchive();
} catch (e) {
this.log.error('error while excluding files from packing to asar: ', e);
process.exit(1);
}
try {
await this.transpileAndMinify();
} catch (e) {
this.log.error('error while transpiling or minifying: ', e);
}
try {
await this.packDesktopToAsar();
} catch (e) {
this.log.error('error occurred while packing .desktop to asar: ', e);
process.exit(1);
}
try {
await this.getMeteorClientBuild();
} catch (e) {
this.log.error('error occurred during getting meteor mobile build: ', e);
}
if (run) {
this.log.info('running');
this.$.electron.run();
} else {
this.log.info('built');
}
}
/**
* Copies the `exposedModules` setting from `settings.json` into `preload.js` modifying its code
* so that the script will have it hardcoded.
*/
exposeElectronModules() {
const {
exposedModules
} = this.$.desktop.getSettings();
if (exposedModules && Array.isArray(exposedModules) && exposedModules.length > 0) {
let preload = _fs.default.readFileSync(this.$.env.paths.electronApp.preload, 'utf8');
const modules = this.$.desktop.getSettings().exposedModules.reduce( // eslint-disable-next-line no-return-assign,no-param-reassign
(prev, module) => (prev += `'${module}', `, prev), '');
preload = preload.replace('const exposedModules = [', `const exposedModules = [${modules}`);
_fs.default.writeFileSync(this.$.env.paths.electronApp.preload, preload);
}
}
/**
* Ensures all required dependencies are added to the Meteor project.
* @returns {Promise.<void>}
*/
async ensureMeteorDependencies() {
let packages = [];
const packagesWithVersion = [];
let plugins = 'plugins [';
Object.keys(this.$.desktop.getDependencies().plugins).forEach(plugin => {
// Read package.json of the plugin.
const packageJson = JSON.parse(_fs.default.readFileSync(_path.default.join(this.$.env.paths.electronApp.nodeModules, plugin, 'package.json'), 'utf8'));
if ('meteorDependencies' in packageJson && typeof packageJson.meteorDependencies === 'object') {
plugins += `${plugin}, `;
packages.unshift(...Object.keys(packageJson.meteorDependencies));
packagesWithVersion.unshift(...packages.map(packageName => {
if (packageJson.meteorDependencies[packageName] === '@version') {
return `${packageName}@${packageJson.version}`;
}
return `${packageName}@${packageJson.meteorDependencies[packageName]}`;
}));
}
});
const packagesCount = packages.length;
packages = packages.filter(value => !this.deprectatedPlugins.includes(value));
if (packagesCount !== packages.length) {
this.log.warn('you have some deprecated meteor desktop plugins in your settings, please remove ' + `them (deprecated plugins: ${this.deprectatedPlugins.join(', ')})`);
}
if (packages.length > 0) {
plugins = `${plugins.substr(0, plugins.length - 2)}]`;
try {
await this.$.meteorApp.meteorManager.ensurePackages(packages, packagesWithVersion, plugins);
} catch (e) {
throw new Error(e);
}
}
}
/**
* Builds meteor app.
*/
async getMeteorClientBuild() {
await this.$.meteorApp.build();
}
/**
* Removes node_modules if needed.
* @returns {Promise<void>}
*/
async handleStateOfNodeModules() {
if (this.$.env.isProductionBuild() || this.$.env.options.ia32) {
if (!this.$.env.isProductionBuild()) {
this.log.info('clearing node_modules because we need to have it clear for ia32 rebuild');
} else {
this.log.info('clearing node_modules because this is a production build');
}
try {
await this.$.utils.rmWithRetries('-rf', this.$.env.paths.electronApp.nodeModules);
} catch (e) {
throw new Error(e);
}
return true;
}
return false;
}
/**
* If there is a temporary node_modules folder and no node_modules folder, we will
* restore it, as it might be a leftover from an interrupted flow.
* @returns {Promise<void>}
*/
async handleTemporaryNodeModules() {
if (this.$.utils.exists(this.$.env.paths.electronApp.tmpNodeModules)) {
if (!this.$.utils.exists(this.$.env.paths.electronApp.nodeModules)) {
this.log.debug('moving temp node_modules back');
_shelljs.default.mv(this.$.env.paths.electronApp.tmpNodeModules, this.$.env.paths.electronApp.nodeModules);
} else {
// If there is a node_modules folder, we should clear the temporary one.
this.log.debug('clearing temp node_modules because new one is already created');
try {
await this.$.utils.rmWithRetries('-rf', this.$.env.paths.electronApp.tmpNodeModules);
} catch (e) {
throw new Error(e);
}
}
}
}
/**
* Runs npm link for every package specified in settings.json->linkPackages.
*/
async linkNpmPackages() {
if (this.$.env.isProductionBuild()) {
return;
}
const settings = this.$.desktop.getSettings();
const promises = [];
if ('linkPackages' in this.$.desktop.getSettings()) {
if (Array.isArray(settings.linkPackages)) {
settings.linkPackages.forEach(packageName => promises.push(this.$.meteorApp.runNpm(['link', packageName], undefined, this.$.env.paths.electronApp.root)));
}
}
await Promise.all(promises);
}
/**
* Runs npm in the electron app to get the dependencies installed.
* @returns {Promise}
*/
async ensureDeps() {
this.log.info('installing dependencies');
if (this.$.utils.exists(this.$.env.paths.electronApp.nodeModules)) {
this.log.debug('running npm prune to wipe unneeded dependencies');
try {
await this.runNpm(['prune']);
} catch (e) {
throw new Error(e);
}
}
try {
await this.runNpm(['install'], this.$.env.stdio);
} catch (e) {
throw new Error(e);
}
}
/**
* Warns if plugins version are outdated in compare to the newest scaffold.
* @param {Object} pluginsVersions - current plugins versions from settings.json
*/
checkPluginsVersion(pluginsVersions) {
const settingsJson = JSON.parse(_fs.default.readFileSync(_path.default.join(this.$.env.paths.scaffold, 'settings.json')));
const scaffoldPluginsVersion = this.$.desktop.getDependencies(settingsJson, false).plugins;
Object.keys(pluginsVersions).forEach(pluginName => {
if (pluginName in scaffoldPluginsVersion && scaffoldPluginsVersion[pluginName] !== pluginsVersions[pluginName] && _semver.default.lt(pluginsVersions[pluginName], scaffoldPluginsVersion[pluginName])) {
this.log.warn(`you are using outdated version ${pluginsVersions[pluginName]} of ` + `${pluginName}, the suggested version to use is ` + `${scaffoldPluginsVersion[pluginName]}`);
}
});
}
/**
* Merges core dependency list with the dependencies from .desktop.
*/
updateDependenciesList() {
this.log.info('updating list of package.json\'s dependencies');
const desktopDependencies = this.$.desktop.getDependencies();
this.checkPluginsVersion(desktopDependencies.plugins);
this.log.debug('merging settings.json[dependencies]');
this.depsManager.mergeDependencies('settings.json[dependencies]', desktopDependencies.fromSettings);
this.log.debug('merging settings.json[plugins]');
this.depsManager.mergeDependencies('settings.json[plugins]', desktopDependencies.plugins);
this.log.debug('merging dependencies from modules');
Object.keys(desktopDependencies.modules).forEach(module => this.depsManager.mergeDependencies(`module[${module}]`, desktopDependencies.modules[module]));
this.packageJson.dependencies = this.depsManager.getRemoteDependencies();
this.packageJson.localDependencies = this.depsManager.getLocalDependencies();
this.log.debug('writing updated package.json');
_fs.default.writeFileSync(this.$.env.paths.electronApp.packageJson, JSON.stringify(this.packageJson, null, 2));
}
/**
* Install node modules from local paths using local-install.
*
* @param {string} arch
* @returns {Promise}
*/
installLocalNodeModules(arch = this.$.env.options.ia32 || process.arch === 'ia32' ? 'ia32' : 'x64') {
const localDependencies = _lodash.default.values(this.packageJson.localDependencies);
if (localDependencies.length === 0) {
return Promise.resolve();
}
this.log.info('installing local node modules');
const lastRebuild = this.$.electronBuilder.prepareLastRebuildObject(arch);
const env = this.$.electronBuilder.getGypEnv(lastRebuild.frameworkInfo, lastRebuild.platform, lastRebuild.arch);
const installer = new _installLocal.LocalInstaller({
[this.$.env.paths.electronApp.root]: localDependencies
}, {
npmEnv: env
});
(0, _installLocal.progress)(installer);
return installer.install();
}
/**
* Rebuild binary dependencies against Electron's node headers.
* @returns {Promise}
*/
rebuildDeps(install = false) {
if (install) {
this.log.info('issuing node_modules install from electron-builder');
} else {
this.log.info('issuing native modules rebuild from electron-builder');
}
const arch = this.$.env.options.ia32 || process.arch === 'ia32' ? 'ia32' : 'x64';
if (this.$.env.options.ia32) {
this.log.verbose('forcing rebuild for 32bit');
} else {
this.log.verbose(`rebuilding for ${arch}`);
}
return this.$.electronBuilder.installOrRebuild(arch, undefined, install);
}
/**
* Update package.json fields accordingly to what is set in settings.json.
*
* packageJson.name = settings.projectName
* packageJson.version = settings.version
* packageJson.* = settings.packageJsonFields
*/
updatePackageJsonFields() {
this.log.verbose('updating package.json fields');
const settings = this.$.desktop.getSettings();
/** @type {desktopSettings} */
const packageJson = this.scaffold.getDefaultPackageJson();
packageJson.version = settings.version;
if ('packageJsonFields' in settings) {
(0, _assignIn.default)(packageJson, settings.packageJsonFields);
}
(0, _assignIn.default)(packageJson, {
name: settings.projectName
});
this.log.debug('writing updated package.json');
_fs.default.writeFileSync(this.$.env.paths.electronApp.packageJson, JSON.stringify(packageJson, null, 4));
this.packageJson = packageJson;
}
/**
* Updates settings.json with env (prod/dev) information and versions.
*/
async updateSettingsJsonFields() {
this.log.debug('updating settings.json fields');
const settings = this.$.desktop.getSettings(); // Save versions.
settings.compatibilityVersion = this.compatibilityVersion; // Pass information about build type to the settings.json.
settings.env = this.$.env.isProductionBuild() ? 'prod' : 'dev';
const version = await this.$.desktop.getHashVersion();
settings.desktopVersion = `${version}_${settings.env}`;
settings.meteorDesktopVersion = this.$.getVersion();
if (this.$.env.options.prodDebug) {
settings.prodDebug = true;
}
_fs.default.writeFileSync(this.$.env.paths.desktopTmp.settings, JSON.stringify(settings, null, 4));
}
/**
* Copies files from prepared .desktop to desktop.asar in electron app.
*/
packDesktopToAsar() {
this.log.info('packing .desktop to asar');
return new Promise((resolve, reject) => {
_asar.default.createPackage(this.$.env.paths.desktopTmp.root, this.$.env.paths.electronApp.desktopAsar, () => {
this.log.verbose('clearing temporary .desktop');
this.$.utils.rmWithRetries('-rf', this.$.env.paths.desktopTmp.root).then(() => {
resolve();
}).catch(e => {
reject(e);
});
resolve();
});
});
}
/**
* Makes a temporary copy of .desktop.
*/
copyDesktopToDesktopTemp() {
this.log.verbose('copying .desktop to temporary location');
_shelljs.default.cp('-rf', this.$.env.paths.desktop.root, this.$.env.paths.desktopTmp.root); // Remove test files.
_del.default.sync([_path.default.join(this.$.env.paths.desktopTmp.root, '**', '*.test.js')], {
force: true
});
}
/**
* Runs babel and uglify over .desktop if requested.
*/
async transpileAndMinify() {
this.log.info('transpiling and uglifying');
const settings = this.$.desktop.getSettings();
const options = 'uglifyOptions' in settings ? settings.uglifyOptions : {};
const uglifyingEnabled = 'uglify' in settings && !!settings.uglify;
const preset = (0, _presetEnv.default)({
assertVersion: () => {}
}, {
targets: {
node: '12'
}
});
const {
data: files
} = await this.$.utils.readDir(this.$.env.paths.desktopTmp.root);
files.forEach(file => {
if (file.endsWith('.js')) {
let {
code
} = (0, _core.transformFileSync)(file, {
presets: [preset]
});
let error;
if (settings.env === 'prod' && uglifyingEnabled) {
({
code,
error
} = _terser.default.minify(code, options));
}
if (error) {
throw new Error(error);
}
_fs.default.writeFileSync(file, code);
}
});
}
/**
* Moves all the files that should not be packed into asar into a safe location which is the
* 'extracted' dir in the electron app.
*/
async excludeFilesFromArchive() {
this.log.info('excluding files from packing'); // Ensure empty `extracted` dir
try {
await this.$.utils.rmWithRetries('-rf', this.$.env.paths.electronApp.extracted);
} catch (e) {
throw new Error(e);
}
_shelljs.default.mkdir(this.$.env.paths.electronApp.extracted);
const configs = this.$.desktop.gatherModuleConfigs(); // Move files that should not be asar'ed.
configs.forEach(config => {
const moduleConfig = config;
if ('extract' in moduleConfig) {
if (!Array.isArray(moduleConfig.extract)) {
moduleConfig.extract = [moduleConfig.extract];
}
moduleConfig.extract.forEach(file => {
this.log.debug(`excluding ${file} from ${config.name}`);
const filePath = _path.default.join(this.$.env.paths.desktopTmp.modules, moduleConfig.dirName, file);
const destinationPath = _path.default.join(this.$.env.paths.electronApp.extracted, moduleConfig.dirName);
if (!this.$.utils.exists(destinationPath)) {
_shelljs.default.mkdir(destinationPath);
}
_shelljs.default.mv(filePath, destinationPath);
});
}
});
}
}
exports.default = ElectronApp;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL2xpYi9lbGVjdHJvbkFwcC5qcyJdLCJuYW1lcyI6WyJzaGVsbCIsImNvbmZpZyIsImZhdGFsIiwiRWxlY3Ryb25BcHAiLCJjb25zdHJ1Y3RvciIsIiQiLCJsb2ciLCJMb2ciLCJzY2FmZm9sZCIsIkVsZWN0cm9uQXBwU2NhZmZvbGQiLCJkZXBzTWFuYWdlciIsIkRlcGVuZGVuY2llc01hbmFnZXIiLCJnZXREZWZhdWx0UGFja2FnZUpzb24iLCJkZXBlbmRlbmNpZXMiLCJtZXRlb3JBcHAiLCJwYWNrYWdlSnNvbiIsInZlcnNpb24iLCJjb21wYXRpYmlsaXR5VmVyc2lvbiIsImRlcHJlY3RhdGVkUGx1Z2lucyIsInBhY2tTa2VsZXRvblRvQXNhciIsImV4Y2x1ZGVGcm9tRGVsIiwiaW5mbyIsIlByb21pc2UiLCJyZXNvbHZlIiwiZXh0cmFjdCIsImdldE1vZHVsZXNUb0V4dHJhY3QiLCJkZWJ1ZyIsImZzIiwicmVuYW1lU3luYyIsImVudiIsInBhdGhzIiwiZWxlY3Ryb25BcHAiLCJub2RlTW9kdWxlcyIsInBhdGgiLCJqb2luIiwiYXBwUm9vdCIsImV4dHJhY3RlZCIsImV4dHJhY3RNb2R1bGVzIiwiYXNhciIsImNyZWF0ZVBhY2thZ2UiLCJhcHBBc2FyIiwibXYiLCJmb3JFYWNoIiwibW9kdWxlIiwiY3AiLCJleHRyYWN0ZWROb2RlTW9kdWxlcyIsInV0aWxzIiwiZXhpc3RzIiwiZXh0cmFjdGVkTm9kZU1vZHVsZXNCaW4iLCJleGNsdWRlIiwiY29uY2F0IiwiZGVsIiwic3luYyIsInJvb3QiLCJzZXAiLCJtYXAiLCJwYXRoVG9FeGNsdWRlIiwiZm9yY2UiLCJleHQiLCJsZW5ndGgiLCJybSIsIm1rZGlyU3luYyIsImV4dHJhY3RCaW4iLCJKU09OIiwicGFyc2UiLCJyZWFkRmlsZVN5bmMiLCJlIiwiYmlucyIsImJpbiIsIk9iamVjdCIsImtleXMiLCJleHRlbnNpb24iLCJiaW5GaWxlUGF0aCIsInN5bWxpbmtFeGlzdHMiLCJiaW5hcnlNb2R1bGVzRGV0ZWN0b3IiLCJCaW5hcnlNb2R1bGVEZXRlY3RvciIsInRvQmVFeHRyYWN0ZWQiLCJkZXRlY3QiLCJkZXNrdG9wIiwiZ2V0U2V0dGluZ3MiLCJBcnJheSIsImlzQXJyYXkiLCJtZXJnZSIsInZlcmJvc2UiLCJjYWxjdWxhdGVDb21wYXRpYmlsaXR5VmVyc2lvbiIsInNldHRpbmdzIiwiZGVza3RvcEhDUENvbXBhdGliaWxpdHlWZXJzaW9uIiwid2FybiIsIm1kNSIsImNyeXB0byIsImNyZWF0ZUhhc2giLCJnZXREZXBlbmRlbmNpZXMiLCJkZXBlbmRlbmNpZXNTb3J0ZWQiLCJzb3J0IiwiZGVwZW5kZW5jeSIsIm1haW5Db21wYXRpYmlsaXR5VmVyc2lvbiIsImdldFZlcnNpb24iLCJzcGxpdCIsInB1c2giLCJkZXNrdG9wQ29tcGF0aWJpbGl0eVZlcnNpb24iLCJwcm9jZXNzIiwiTUVURU9SX0RFU0tUT1BfREVCVUdfREVTS1RPUF9DT01QQVRJQklMSVRZX1ZFUlNJT04iLCJNRVRFT1JfREVTS1RPUF9ERUJVRyIsInN0cmluZ2lmeSIsInVwZGF0ZSIsImRpZ2VzdCIsImluaXQiLCJlbGVjdHJvbiIsImVsZWN0cm9uQnVpbGRlciIsImV4aXQiLCJidWlsZCIsInJ1biIsImNoZWNrIiwib3B0aW9ucyIsImVycm9yIiwidXBkYXRlR2l0SWdub3JlIiwicm9vdE5hbWUiLCJyZW1vdmVEZXByZWNhdGVkUGFja2FnZXMiLCJlbnN1cmVEZXNrdG9wSENQUGFja2FnZXMiLCJtYWtlIiwiZmlsZU5hbWUiLCJkaXJOYW1lIiwiZXhpc3RzU3luYyIsImNvcHlGaWxlU3luYyIsImV4cG9zZUVsZWN0cm9uTW9kdWxlcyIsInVwZGF0ZVBhY2thZ2VKc29uRmllbGRzIiwidXBkYXRlRGVwZW5kZW5jaWVzTGlzdCIsImhhbmRsZVRlbXBvcmFyeU5vZGVNb2R1bGVzIiwibm9kZU1vZHVsZXNSZW1vdmVkIiwiaGFuZGxlU3RhdGVPZk5vZGVNb2R1bGVzIiwicmVidWlsZERlcHMiLCJsaW5rTnBtUGFja2FnZXMiLCJpbnN0YWxsTG9jYWxOb2RlTW9kdWxlcyIsImVuc3VyZU1ldGVvckRlcGVuZGVuY2llcyIsImlzUHJvZHVjdGlvbkJ1aWxkIiwiY29weURlc2t0b3BUb0Rlc2t0b3BUZW1wIiwidXBkYXRlU2V0dGluZ3NKc29uRmllbGRzIiwiZXhjbHVkZUZpbGVzRnJvbUFyY2hpdmUiLCJ0cmFuc3BpbGVBbmRNaW5pZnkiLCJwYWNrRGVza3RvcFRvQXNhciIsImdldE1ldGVvckNsaWVudEJ1aWxkIiwiZXhwb3NlZE1vZHVsZXMiLCJwcmVsb2FkIiwibW9kdWxlcyIsInJlZHVjZSIsInByZXYiLCJyZXBsYWNlIiwid3JpdGVGaWxlU3luYyIsInBhY2thZ2VzIiwicGFja2FnZXNXaXRoVmVyc2lvbiIsInBsdWdpbnMiLCJwbHVnaW4iLCJtZXRlb3JEZXBlbmRlbmNpZXMiLCJ1bnNoaWZ0IiwicGFja2FnZU5hbWUiLCJwYWNrYWdlc0NvdW50IiwiZmlsdGVyIiwidmFsdWUiLCJpbmNsdWRlcyIsInN1YnN0ciIsIm1ldGVvck1hbmFnZXIiLCJlbnN1cmVQYWNrYWdlcyIsIkVycm9yIiwiaWEzMiIsInJtV2l0aFJldHJpZXMiLCJ0bXBOb2RlTW9kdWxlcyIsInByb21pc2VzIiwibGlua1BhY2thZ2VzIiwicnVuTnBtIiwidW5kZWZpbmVkIiwiYWxsIiwiZW5zdXJlRGVwcyIsInN0ZGlvIiwiY2hlY2tQbHVnaW5zVmVyc2lvbiIsInBsdWdpbnNWZXJzaW9ucyIsInNldHRpbmdzSnNvbiIsInNjYWZmb2xkUGx1Z2luc1ZlcnNpb24iLCJwbHVnaW5OYW1lIiwic2VtdmVyIiwibHQiLCJkZXNrdG9wRGVwZW5kZW5jaWVzIiwibWVyZ2VEZXBlbmRlbmNpZXMiLCJmcm9tU2V0dGluZ3MiLCJnZXRSZW1vdGVEZXBlbmRlbmNpZXMiLCJsb2NhbERlcGVuZGVuY2llcyIsImdldExvY2FsRGVwZW5kZW5jaWVzIiwiYXJjaCIsIl8iLCJ2YWx1ZXMiLCJsYXN0UmVidWlsZCIsInByZXBhcmVMYXN0UmVidWlsZE9iamVjdCIsImdldEd5cEVudiIsImZyYW1ld29ya0luZm8iLCJwbGF0Zm9ybSIsImluc3RhbGxlciIsIkxvY2FsSW5zdGFsbGVyIiwibnBtRW52IiwiaW5zdGFsbCIsImluc3RhbGxPclJlYnVpbGQiLCJwYWNrYWdlSnNvbkZpZWxkcyIsIm5hbWUiLCJwcm9qZWN0TmFtZSIsImdldEhhc2hWZXJzaW9uIiwiZGVza3RvcFZlcnNpb24iLCJtZXRlb3JEZXNrdG9wVmVyc2lvbiIsInByb2REZWJ1ZyIsImRlc2t0b3BUbXAiLCJyZWplY3QiLCJkZXNrdG9wQXNhciIsInRoZW4iLCJjYXRjaCIsInVnbGlmeU9wdGlvbnMiLCJ1Z2xpZnlpbmdFbmFibGVkIiwidWdsaWZ5IiwicHJlc2V0IiwiYXNzZXJ0VmVyc2lvbiIsInRhcmdldHMiLCJub2RlIiwiZGF0YSIsImZpbGVzIiwicmVhZERpciIsImZpbGUiLCJlbmRzV2l0aCIsImNvZGUiLCJwcmVzZXRzIiwibWluaWZ5IiwibWtkaXIiLCJjb25maWdzIiwiZ2F0aGVyTW9kdWxlQ29uZmlncyIsIm1vZHVsZUNvbmZpZyIsImZpbGVQYXRoIiwiZGVzdGluYXRpb25QYXRoIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFuQkE7QUFxQkFBLGlCQUFNQyxNQUFOLENBQWFDLEtBQWIsR0FBcUIsSUFBckI7QUFFQTs7Ozs7QUFJZSxNQUFNQyxXQUFOLENBQWtCO0FBQzdCOzs7O0FBSUFDLEVBQUFBLFdBQVcsQ0FBQ0MsQ0FBRCxFQUFJO0FBQ1gsU0FBS0MsR0FBTCxHQUFXLElBQUlDLFlBQUosQ0FBUSxhQUFSLENBQVg7QUFDQSxTQUFLQyxRQUFMLEdBQWdCLElBQUlDLDRCQUFKLENBQXdCSixDQUF4QixDQUFoQjtBQUNBLFNBQUtLLFdBQUwsR0FBbUIsSUFBSUMsNEJBQUosQ0FDZk4sQ0FEZSxFQUVmLEtBQUtH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