UNPKG

@jasonscheirer/electron-forge-maker-msix

Version:

An `electron-forge` maker for MSIX that supports `electron-forge` v6 and can be used as a replacement for `electron-builder`. Supports code-signing.

153 lines 7.17 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const maker_base_1 = require("@electron-forge/maker-base"); const yaml_1 = require("./yaml"); const fs_extra_1 = __importDefault(require("fs-extra")); const node_path_1 = __importDefault(require("node:path")); const imageAssets_1 = require("./imageAssets"); const msixTools_1 = require("./msixTools"); const run_1 = require("./run"); const sign_1 = require("./sign"); const walk_1 = require("./walk"); __exportStar(require("./msixTools"), exports); __exportStar(require("./imageAssets"), exports); __exportStar(require("./types"), exports); const findMainExecutable = async (rootPath) => { let executable; for await (const fileName of (0, walk_1.walk)(rootPath)) { const relativeFileName = fileName.substring(rootPath.length).replace(/^[\\/]+/, ''); if (relativeFileName.toLocaleLowerCase().endsWith('.exe') && (!executable || executable.split(/[/\\]/).length > relativeFileName.split(/[/\\]/).length)) { executable = relativeFileName; } } if (!executable) { throw new Error(`No executable file found in ${rootPath}`); } return executable; }; const packageMSIXFromFolder = async (scratchPath, outMSIX, config) => { var _a; const makeAppXPath = (_a = config.makeAppXPath) !== null && _a !== void 0 ? _a : (await (0, walk_1.findInWindowsKits)('makeappx.exe')); await (0, sign_1.codesign)(config, scratchPath); try { if ((await fs_extra_1.default.stat(outMSIX)).isFile()) { (0, run_1.log)(`${outMSIX} already exists; making new one`); await fs_extra_1.default.unlink(outMSIX); } } catch (e) { (0, run_1.log)(`Error looking for existing ${outMSIX}: ${e}`); } await (0, run_1.run)(makeAppXPath, ['pack', '/d', scratchPath, '/p', outMSIX]); await (0, sign_1.codesign)(config, outMSIX); }; const makeAppUpdateYml = async (config, options, outPath) => { if (!config.updater) return; const ymlContents = await (0, yaml_1.getAppUpdateYml)({ url: config.updater.url, name: options.appName, channel: config.updater.channel, updaterCacheDirName: config.updater.updaterCacheDirName, publisherName: config.updater.publisherName, }); const resourcePath = node_path_1.default.join(outPath, 'resources'); (0, run_1.log)(`Writing app-update.yml to ${resourcePath}`, ymlContents); await fs_extra_1.default.ensureDir(resourcePath); await fs_extra_1.default.writeFile(node_path_1.default.join(resourcePath, 'app-update.yml'), ymlContents, 'utf8'); }; const makeChannelYml = async (config, options, installerPath) => { if (!config.updater) return; const channel = config.updater.channel || 'latest'; const version = options.packageJSON.version; const channelFilePath = node_path_1.default.resolve(installerPath, `${channel}.yml`); const ymlContents = await (0, yaml_1.getChannelYml)({ installerPath, version, platform: 'win32', }); (0, run_1.log)(`Writing ${channel}.yml to ${installerPath}`, ymlContents); await fs_extra_1.default.writeFile(channelFilePath, ymlContents, 'utf8'); return channelFilePath; }; class MakerMSIX extends maker_base_1.MakerBase { constructor() { super(...arguments); this.name = 'msix'; this.defaultPlatforms = ['win32']; } isSupportedOnCurrentPlatform() { return process.platform === 'win32'; } async make(options) { var _a; const appID = (_a = this.config.internalAppID) !== null && _a !== void 0 ? _a : options.appName .toUpperCase() .replace(/[^A-Z]/g, '') .slice(0, 10); // Copy out files to scratch directory for signing/packaging const msixBuildFolderRootPath = node_path_1.default.join(options.makeDir, 'msix/build/'); if (await fs_extra_1.default.pathExists(msixBuildFolderRootPath)) { await fs_extra_1.default.remove(msixBuildFolderRootPath); } const programFilesPath = node_path_1.default.join(msixBuildFolderRootPath, options.appName); await fs_extra_1.default.ensureDir(programFilesPath); await fs_extra_1.default.copy(options.dir, programFilesPath); // Make sure the build dir exists const outPath = node_path_1.default.join(options.makeDir, `${options.appName}-${options.targetArch}-msix/`); await fs_extra_1.default.ensureDir(outPath); // Find all the files to be installed const executable = await findMainExecutable(msixBuildFolderRootPath); // Generate images for various tile sizes await (0, imageAssets_1.makeAppXImages)(appID, msixBuildFolderRootPath, this.config); // Courtesy: if publisher is not set, pull from signed exe let publisher; if (this.config.publisher) { publisher = this.config.publisher; } else { publisher = await (0, msixTools_1.getPublisher)(node_path_1.default.join(msixBuildFolderRootPath, executable), this.config); } const manifestConfig = (0, msixTools_1.makeManifestConfiguration)({ appID, version: options.packageJSON.version, executable, config: { ...this.config, publisher, }, options, }); // Actual AppxManifest.xml, the orchestration layer const appInstallerPath = await (0, msixTools_1.makeAppInstaller)(outPath, msixBuildFolderRootPath, manifestConfig); await (0, msixTools_1.makePRI)(msixBuildFolderRootPath, this.config); await makeAppUpdateYml(this.config, options, programFilesPath); await (0, msixTools_1.makeAppManifest)(msixBuildFolderRootPath, manifestConfig); await (0, msixTools_1.makeContentTypeXML)(msixBuildFolderRootPath); const outMSIX = node_path_1.default.join(outPath, manifestConfig.msixFilename); await packageMSIXFromFolder(msixBuildFolderRootPath, outMSIX, this.config); const channelYamlPath = await makeChannelYml(this.config, options, outPath); return [outMSIX, appInstallerPath, channelYamlPath].filter(Boolean); } } exports.default = MakerMSIX; //# sourceMappingURL=makerMsix.js.map