@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
JavaScript
;
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