This commit is contained in:
root
2025-11-25 09:56:15 +03:00
commit 68c8f0e80d
23717 changed files with 3200521 additions and 0 deletions

View File

@ -0,0 +1,16 @@
export declare enum AsarMode {
NO_ASAR = 0,
HAS_ASAR = 1
}
export declare type MergeASARsOptions = {
x64AsarPath: string;
arm64AsarPath: string;
outputAsarPath: string;
singleArchFiles?: string;
};
export declare const detectAsarMode: (appPath: string) => Promise<AsarMode>;
export declare const generateAsarIntegrity: (asarPath: string) => {
algorithm: "SHA256";
hash: string;
};
export declare const mergeASARs: ({ x64AsarPath, arm64AsarPath, outputAsarPath, singleArchFiles, }: MergeASARsOptions) => Promise<void>;

View File

@ -0,0 +1,169 @@
import asar from '@electron/asar';
import { execFileSync } from 'child_process';
import crypto from 'crypto';
import fs from 'fs-extra';
import path from 'path';
import minimatch from 'minimatch';
import os from 'os';
import { d } from './debug';
const LIPO = 'lipo';
export var AsarMode;
(function (AsarMode) {
AsarMode[AsarMode["NO_ASAR"] = 0] = "NO_ASAR";
AsarMode[AsarMode["HAS_ASAR"] = 1] = "HAS_ASAR";
})(AsarMode || (AsarMode = {}));
// See: https://github.com/apple-opensource-mirror/llvmCore/blob/0c60489d96c87140db9a6a14c6e82b15f5e5d252/include/llvm/Object/MachOFormat.h#L108-L112
const MACHO_MAGIC = new Set([
// 32-bit Mach-O
0xfeedface,
0xcefaedfe,
// 64-bit Mach-O
0xfeedfacf,
0xcffaedfe,
]);
const MACHO_UNIVERSAL_MAGIC = new Set([
// universal
0xcafebabe,
0xbebafeca,
]);
export const detectAsarMode = async (appPath) => {
d('checking asar mode of', appPath);
const asarPath = path.resolve(appPath, 'Contents', 'Resources', 'app.asar');
if (!(await fs.pathExists(asarPath))) {
d('determined no asar');
return AsarMode.NO_ASAR;
}
d('determined has asar');
return AsarMode.HAS_ASAR;
};
export const generateAsarIntegrity = (asarPath) => {
return {
algorithm: 'SHA256',
hash: crypto
.createHash('SHA256')
.update(asar.getRawHeader(asarPath).headerString)
.digest('hex'),
};
};
function toRelativePath(file) {
return file.replace(/^\//, '');
}
function isDirectory(a, file) {
return Boolean('files' in asar.statFile(a, file));
}
function checkSingleArch(archive, file, allowList) {
if (allowList === undefined || !minimatch(file, allowList, { matchBase: true })) {
throw new Error(`Detected unique file "${file}" in "${archive}" not covered by ` +
`allowList rule: "${allowList}"`);
}
}
export const mergeASARs = async ({ x64AsarPath, arm64AsarPath, outputAsarPath, singleArchFiles, }) => {
d(`merging ${x64AsarPath} and ${arm64AsarPath}`);
const x64Files = new Set(asar.listPackage(x64AsarPath).map(toRelativePath));
const arm64Files = new Set(asar.listPackage(arm64AsarPath).map(toRelativePath));
//
// Build set of unpacked directories and files
//
const unpackedFiles = new Set();
function buildUnpacked(a, fileList) {
for (const file of fileList) {
const stat = asar.statFile(a, file);
if (!('unpacked' in stat) || !stat.unpacked) {
continue;
}
if ('files' in stat) {
continue;
}
unpackedFiles.add(file);
}
}
buildUnpacked(x64AsarPath, x64Files);
buildUnpacked(arm64AsarPath, arm64Files);
//
// Build list of files/directories unique to each asar
//
for (const file of x64Files) {
if (!arm64Files.has(file)) {
checkSingleArch(x64AsarPath, file, singleArchFiles);
}
}
const arm64Unique = [];
for (const file of arm64Files) {
if (!x64Files.has(file)) {
checkSingleArch(arm64AsarPath, file, singleArchFiles);
arm64Unique.push(file);
}
}
//
// Find common bindings with different content
//
const commonBindings = [];
for (const file of x64Files) {
if (!arm64Files.has(file)) {
continue;
}
// Skip directories
if (isDirectory(x64AsarPath, file)) {
continue;
}
const x64Content = asar.extractFile(x64AsarPath, file);
const arm64Content = asar.extractFile(arm64AsarPath, file);
if (x64Content.compare(arm64Content) === 0) {
continue;
}
if (MACHO_UNIVERSAL_MAGIC.has(x64Content.readUInt32LE(0)) &&
MACHO_UNIVERSAL_MAGIC.has(arm64Content.readUInt32LE(0))) {
continue;
}
if (!MACHO_MAGIC.has(x64Content.readUInt32LE(0))) {
throw new Error(`Can't reconcile two non-macho files ${file}`);
}
commonBindings.push(file);
}
//
// Extract both
//
const x64Dir = await fs.mkdtemp(path.join(os.tmpdir(), 'x64-'));
const arm64Dir = await fs.mkdtemp(path.join(os.tmpdir(), 'arm64-'));
try {
d(`extracting ${x64AsarPath} to ${x64Dir}`);
asar.extractAll(x64AsarPath, x64Dir);
d(`extracting ${arm64AsarPath} to ${arm64Dir}`);
asar.extractAll(arm64AsarPath, arm64Dir);
for (const file of arm64Unique) {
const source = path.resolve(arm64Dir, file);
const destination = path.resolve(x64Dir, file);
if (isDirectory(arm64AsarPath, file)) {
d(`creating unique directory: ${file}`);
await fs.mkdirp(destination);
continue;
}
d(`xopying unique file: ${file}`);
await fs.mkdirp(path.dirname(destination));
await fs.copy(source, destination);
}
for (const binding of commonBindings) {
const source = await fs.realpath(path.resolve(arm64Dir, binding));
const destination = await fs.realpath(path.resolve(x64Dir, binding));
d(`merging binding: ${binding}`);
execFileSync(LIPO, [source, destination, '-create', '-output', destination]);
}
d(`creating archive at ${outputAsarPath}`);
const resolvedUnpack = Array.from(unpackedFiles).map((file) => path.join(x64Dir, file));
let unpack;
if (resolvedUnpack.length > 1) {
unpack = `{${resolvedUnpack.join(',')}}`;
}
else if (resolvedUnpack.length === 1) {
unpack = resolvedUnpack[0];
}
await asar.createPackageWithOptions(x64Dir, outputAsarPath, {
unpack,
});
d('done merging');
}
finally {
await Promise.all([fs.remove(x64Dir), fs.remove(arm64Dir)]);
}
};
//# sourceMappingURL=asar-utils.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
import debug from 'debug';
export declare const d: debug.Debugger;

3
mc_test/node_modules/@electron/universal/dist/esm/debug.js generated vendored Executable file
View File

@ -0,0 +1,3 @@
import debug from 'debug';
export const d = debug('electron-universal');
//# sourceMappingURL=debug.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../../src/debug.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,oBAAoB,CAAC,CAAC"}

View File

@ -0,0 +1,16 @@
export declare enum AppFileType {
MACHO = 0,
PLAIN = 1,
INFO_PLIST = 2,
SNAPSHOT = 3,
APP_CODE = 4
}
export declare type AppFile = {
relativePath: string;
type: AppFileType;
};
/**
*
* @param appPath Path to the application
*/
export declare const getAllAppFiles: (appPath: string) => Promise<AppFile[]>;

View File

@ -0,0 +1,68 @@
import { spawn, ExitCodeError } from '@malept/cross-spawn-promise';
import * as fs from 'fs-extra';
import * as path from 'path';
const MACHO_PREFIX = 'Mach-O ';
export var AppFileType;
(function (AppFileType) {
AppFileType[AppFileType["MACHO"] = 0] = "MACHO";
AppFileType[AppFileType["PLAIN"] = 1] = "PLAIN";
AppFileType[AppFileType["INFO_PLIST"] = 2] = "INFO_PLIST";
AppFileType[AppFileType["SNAPSHOT"] = 3] = "SNAPSHOT";
AppFileType[AppFileType["APP_CODE"] = 4] = "APP_CODE";
})(AppFileType || (AppFileType = {}));
/**
*
* @param appPath Path to the application
*/
export const getAllAppFiles = async (appPath) => {
const files = [];
const visited = new Set();
const traverse = async (p) => {
p = await fs.realpath(p);
if (visited.has(p))
return;
visited.add(p);
const info = await fs.stat(p);
if (info.isSymbolicLink())
return;
if (info.isFile()) {
let fileType = AppFileType.PLAIN;
var fileOutput = '';
try {
fileOutput = await spawn('file', ['--brief', '--no-pad', p]);
}
catch (e) {
if (e instanceof ExitCodeError) {
/* silently accept error codes from "file" */
}
else {
throw e;
}
}
if (p.includes('app.asar')) {
fileType = AppFileType.APP_CODE;
}
else if (fileOutput.startsWith(MACHO_PREFIX)) {
fileType = AppFileType.MACHO;
}
else if (p.endsWith('.bin')) {
fileType = AppFileType.SNAPSHOT;
}
else if (path.basename(p) === 'Info.plist') {
fileType = AppFileType.INFO_PLIST;
}
files.push({
relativePath: path.relative(appPath, p),
type: fileType,
});
}
if (info.isDirectory()) {
for (const child of await fs.readdir(p)) {
await traverse(path.resolve(p, child));
}
}
};
await traverse(appPath);
return files;
};
//# sourceMappingURL=file-utils.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"file-utils.js","sourceRoot":"","sources":["../../src/file-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,MAAM,YAAY,GAAG,SAAS,CAAC;AAE/B,MAAM,CAAN,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,+CAAK,CAAA;IACL,+CAAK,CAAA;IACL,yDAAU,CAAA;IACV,qDAAQ,CAAA;IACR,qDAAQ,CAAA;AACV,CAAC,EANW,WAAW,KAAX,WAAW,QAMtB;AAOD;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,OAAe,EAAsB,EAAE;IAC1E,MAAM,KAAK,GAAc,EAAE,CAAC;IAE5B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAS,EAAE,EAAE;QACnC,CAAC,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,OAAO;QAC3B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAEf,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,cAAc,EAAE;YAAE,OAAO;QAClC,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE;YACjB,IAAI,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC;YAEjC,IAAI,UAAU,GAAG,EAAE,CAAC;YACpB,IAAI;gBACF,UAAU,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;aAC9D;YAAC,OAAO,CAAC,EAAE;gBACV,IAAI,CAAC,YAAY,aAAa,EAAE;oBAC9B,6CAA6C;iBAC9C;qBAAM;oBACL,MAAM,CAAC,CAAC;iBACT;aACF;YACD,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE;gBAC1B,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC;aACjC;iBAAM,IAAI,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE;gBAC9C,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC;aAC9B;iBAAM,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;gBAC7B,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC;aACjC;iBAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,YAAY,EAAE;gBAC5C,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC;aACnC;YAED,KAAK,CAAC,IAAI,CAAC;gBACT,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;gBACvC,IAAI,EAAE,QAAQ;aACf,CAAC,CAAC;SACJ;QAED,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;YACtB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;gBACvC,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;aACxC;SACF;IACH,CAAC,CAAC;IACF,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;IAExB,OAAO,KAAK,CAAC;AACf,CAAC,CAAC"}

37
mc_test/node_modules/@electron/universal/dist/esm/index.d.ts generated vendored Executable file
View File

@ -0,0 +1,37 @@
export declare type MakeUniversalOpts = {
/**
* Absolute file system path to the x64 version of your application. E.g. /Foo/bar/MyApp_x64.app
*/
x64AppPath: string;
/**
* Absolute file system path to the arm64 version of your application. E.g. /Foo/bar/MyApp_arm64.app
*/
arm64AppPath: string;
/**
* Absolute file system path you want the universal app to be written to. E.g. /Foo/var/MyApp_universal.app
*
* If this file exists it will be overwritten ONLY if "force" is set to true
*/
outAppPath: string;
/**
* Forcefully overwrite any existing files that are in the way of generating the universal application
*/
force: boolean;
/**
* Merge x64 and arm64 ASARs into one.
*/
mergeASARs?: boolean;
/**
* Minimatch pattern of paths that are allowed to be present in one of the ASAR files, but not in the other.
*/
singleArchFiles?: string;
/**
* Minimatch pattern of binaries that are expected to be the same x64 binary in both of the ASAR files.
*/
x64ArchFiles?: string;
/**
* Minimatch pattern of paths that should not receive an injected ElectronAsarIntegrity value
*/
infoPlistsToIgnore?: string;
};
export declare const makeUniversalApp: (opts: MakeUniversalOpts) => Promise<void>;

228
mc_test/node_modules/@electron/universal/dist/esm/index.js generated vendored Executable file
View File

@ -0,0 +1,228 @@
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { spawn } from '@malept/cross-spawn-promise';
import * as asar from '@electron/asar';
import * as fs from 'fs-extra';
import minimatch from 'minimatch';
import * as os from 'os';
import * as path from 'path';
import * as plist from 'plist';
import * as dircompare from 'dir-compare';
import { AppFileType, getAllAppFiles } from './file-utils';
import { AsarMode, detectAsarMode, generateAsarIntegrity, mergeASARs } from './asar-utils';
import { sha } from './sha';
import { d } from './debug';
const dupedFiles = (files) => files.filter((f) => f.type !== AppFileType.SNAPSHOT && f.type !== AppFileType.APP_CODE);
export const makeUniversalApp = async (opts) => {
d('making a universal app with options', opts);
if (process.platform !== 'darwin')
throw new Error('@electron/universal is only supported on darwin platforms');
if (!opts.x64AppPath || !path.isAbsolute(opts.x64AppPath))
throw new Error('Expected opts.x64AppPath to be an absolute path but it was not');
if (!opts.arm64AppPath || !path.isAbsolute(opts.arm64AppPath))
throw new Error('Expected opts.arm64AppPath to be an absolute path but it was not');
if (!opts.outAppPath || !path.isAbsolute(opts.outAppPath))
throw new Error('Expected opts.outAppPath to be an absolute path but it was not');
if (await fs.pathExists(opts.outAppPath)) {
d('output path exists already');
if (!opts.force) {
throw new Error(`The out path "${opts.outAppPath}" already exists and force is not set to true`);
}
else {
d('overwriting existing application because force == true');
await fs.remove(opts.outAppPath);
}
}
const x64AsarMode = await detectAsarMode(opts.x64AppPath);
const arm64AsarMode = await detectAsarMode(opts.arm64AppPath);
d('detected x64AsarMode =', x64AsarMode);
d('detected arm64AsarMode =', arm64AsarMode);
if (x64AsarMode !== arm64AsarMode)
throw new Error('Both the x64 and arm64 versions of your application need to have been built with the same asar settings (enabled vs disabled)');
const tmpDir = await fs.mkdtemp(path.resolve(os.tmpdir(), 'electron-universal-'));
d('building universal app in', tmpDir);
try {
d('copying x64 app as starter template');
const tmpApp = path.resolve(tmpDir, 'Tmp.app');
await spawn('cp', ['-R', opts.x64AppPath, tmpApp]);
const uniqueToX64 = [];
const uniqueToArm64 = [];
const x64Files = await getAllAppFiles(await fs.realpath(tmpApp));
const arm64Files = await getAllAppFiles(await fs.realpath(opts.arm64AppPath));
for (const file of dupedFiles(x64Files)) {
if (!arm64Files.some((f) => f.relativePath === file.relativePath))
uniqueToX64.push(file.relativePath);
}
for (const file of dupedFiles(arm64Files)) {
if (!x64Files.some((f) => f.relativePath === file.relativePath))
uniqueToArm64.push(file.relativePath);
}
if (uniqueToX64.length !== 0 || uniqueToArm64.length !== 0) {
d('some files were not in both builds, aborting');
console.error({
uniqueToX64,
uniqueToArm64,
});
throw new Error('While trying to merge mach-o files across your apps we found a mismatch, the number of mach-o files is not the same between the arm64 and x64 builds');
}
for (const file of x64Files.filter((f) => f.type === AppFileType.PLAIN)) {
const x64Sha = await sha(path.resolve(opts.x64AppPath, file.relativePath));
const arm64Sha = await sha(path.resolve(opts.arm64AppPath, file.relativePath));
if (x64Sha !== arm64Sha) {
d('SHA for file', file.relativePath, `does not match across builds ${x64Sha}!=${arm64Sha}`);
// The MainMenu.nib files generated by Xcode13 are deterministic in effect but not deterministic in generated sequence
if (path.basename(path.dirname(file.relativePath)) === 'MainMenu.nib') {
// The mismatch here is OK so we just move on to the next one
continue;
}
throw new Error(`Expected all non-binary files to have identical SHAs when creating a universal build but "${file.relativePath}" did not`);
}
}
for (const machOFile of x64Files.filter((f) => f.type === AppFileType.MACHO)) {
const first = await fs.realpath(path.resolve(tmpApp, machOFile.relativePath));
const second = await fs.realpath(path.resolve(opts.arm64AppPath, machOFile.relativePath));
const x64Sha = await sha(path.resolve(opts.x64AppPath, machOFile.relativePath));
const arm64Sha = await sha(path.resolve(opts.arm64AppPath, machOFile.relativePath));
if (x64Sha === arm64Sha) {
if (opts.x64ArchFiles === undefined ||
!minimatch(machOFile.relativePath, opts.x64ArchFiles, { matchBase: true })) {
throw new Error(`Detected file "${machOFile.relativePath}" that's the same in both x64 and arm64 builds and not covered by the ` +
`x64ArchFiles rule: "${opts.x64ArchFiles}"`);
}
d('SHA for Mach-O file', machOFile.relativePath, `matches across builds ${x64Sha}===${arm64Sha}, skipping lipo`);
continue;
}
d('joining two MachO files with lipo', {
first,
second,
});
await spawn('lipo', [
first,
second,
'-create',
'-output',
await fs.realpath(path.resolve(tmpApp, machOFile.relativePath)),
]);
}
/**
* If we don't have an ASAR we need to check if the two "app" folders are identical, if
* they are then we can just leave one there and call it a day. If the app folders for x64
* and arm64 are different though we need to rename each folder and create a new fake "app"
* entrypoint to dynamically load the correct app folder
*/
if (x64AsarMode === AsarMode.NO_ASAR) {
d('checking if the x64 and arm64 app folders are identical');
const comparison = await dircompare.compare(path.resolve(tmpApp, 'Contents', 'Resources', 'app'), path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app'), { compareSize: true, compareContent: true });
if (!comparison.same) {
d('x64 and arm64 app folders are different, creating dynamic entry ASAR');
await fs.move(path.resolve(tmpApp, 'Contents', 'Resources', 'app'), path.resolve(tmpApp, 'Contents', 'Resources', 'app-x64'));
await fs.copy(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app'), path.resolve(tmpApp, 'Contents', 'Resources', 'app-arm64'));
const entryAsar = path.resolve(tmpDir, 'entry-asar');
await fs.mkdir(entryAsar);
await fs.copy(path.resolve(__dirname, '..', '..', 'entry-asar', 'no-asar.js'), path.resolve(entryAsar, 'index.js'));
let pj = await fs.readJson(path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app', 'package.json'));
pj.main = 'index.js';
await fs.writeJson(path.resolve(entryAsar, 'package.json'), pj);
await asar.createPackage(entryAsar, path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'));
}
else {
d('x64 and arm64 app folders are the same');
}
}
const generatedIntegrity = {};
let didSplitAsar = false;
/**
* If we have an ASAR we just need to check if the two "app.asar" files have the same hash,
* if they are, same as above, we can leave one there and call it a day. If they're different
* we have to make a dynamic entrypoint. There is an assumption made here that every file in
* app.asar.unpacked is a native node module. This assumption _may_ not be true so we should
* look at codifying that assumption as actual logic.
*/
// FIXME: Codify the assumption that app.asar.unpacked only contains native modules
if (x64AsarMode === AsarMode.HAS_ASAR && opts.mergeASARs) {
d('merging x64 and arm64 asars');
const output = path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar');
await mergeASARs({
x64AsarPath: path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'),
arm64AsarPath: path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar'),
outputAsarPath: output,
singleArchFiles: opts.singleArchFiles,
});
generatedIntegrity['Resources/app.asar'] = generateAsarIntegrity(output);
}
else if (x64AsarMode === AsarMode.HAS_ASAR) {
d('checking if the x64 and arm64 asars are identical');
const x64AsarSha = await sha(path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'));
const arm64AsarSha = await sha(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar'));
if (x64AsarSha !== arm64AsarSha) {
didSplitAsar = true;
d('x64 and arm64 asars are different');
const x64AsarPath = path.resolve(tmpApp, 'Contents', 'Resources', 'app-x64.asar');
await fs.move(path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'), x64AsarPath);
const x64Unpacked = path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar.unpacked');
if (await fs.pathExists(x64Unpacked)) {
await fs.move(x64Unpacked, path.resolve(tmpApp, 'Contents', 'Resources', 'app-x64.asar.unpacked'));
}
const arm64AsarPath = path.resolve(tmpApp, 'Contents', 'Resources', 'app-arm64.asar');
await fs.copy(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar'), arm64AsarPath);
const arm64Unpacked = path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar.unpacked');
if (await fs.pathExists(arm64Unpacked)) {
await fs.copy(arm64Unpacked, path.resolve(tmpApp, 'Contents', 'Resources', 'app-arm64.asar.unpacked'));
}
const entryAsar = path.resolve(tmpDir, 'entry-asar');
await fs.mkdir(entryAsar);
await fs.copy(path.resolve(__dirname, '..', '..', 'entry-asar', 'has-asar.js'), path.resolve(entryAsar, 'index.js'));
let pj = JSON.parse((await asar.extractFile(path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app.asar'), 'package.json')).toString('utf8'));
pj.main = 'index.js';
await fs.writeJson(path.resolve(entryAsar, 'package.json'), pj);
const asarPath = path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar');
await asar.createPackage(entryAsar, asarPath);
generatedIntegrity['Resources/app.asar'] = generateAsarIntegrity(asarPath);
generatedIntegrity['Resources/app-x64.asar'] = generateAsarIntegrity(x64AsarPath);
generatedIntegrity['Resources/app-arm64.asar'] = generateAsarIntegrity(arm64AsarPath);
}
else {
d('x64 and arm64 asars are the same');
generatedIntegrity['Resources/app.asar'] = generateAsarIntegrity(path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'));
}
}
const plistFiles = x64Files.filter((f) => f.type === AppFileType.INFO_PLIST);
for (const plistFile of plistFiles) {
const x64PlistPath = path.resolve(opts.x64AppPath, plistFile.relativePath);
const arm64PlistPath = path.resolve(opts.arm64AppPath, plistFile.relativePath);
const _a = plist.parse(await fs.readFile(x64PlistPath, 'utf8')), { ElectronAsarIntegrity: x64Integrity } = _a, x64Plist = __rest(_a, ["ElectronAsarIntegrity"]);
const _b = plist.parse(await fs.readFile(arm64PlistPath, 'utf8')), { ElectronAsarIntegrity: arm64Integrity } = _b, arm64Plist = __rest(_b, ["ElectronAsarIntegrity"]);
if (JSON.stringify(x64Plist) !== JSON.stringify(arm64Plist)) {
throw new Error(`Expected all Info.plist files to be identical when ignoring integrity when creating a universal build but "${plistFile.relativePath}" was not`);
}
const injectAsarIntegrity = !opts.infoPlistsToIgnore ||
minimatch(plistFile.relativePath, opts.infoPlistsToIgnore, { matchBase: true });
const mergedPlist = injectAsarIntegrity
? Object.assign(Object.assign({}, x64Plist), { ElectronAsarIntegrity: generatedIntegrity }) : Object.assign({}, x64Plist);
await fs.writeFile(path.resolve(tmpApp, plistFile.relativePath), plist.build(mergedPlist));
}
for (const snapshotsFile of arm64Files.filter((f) => f.type === AppFileType.SNAPSHOT)) {
d('copying snapshot file', snapshotsFile.relativePath, 'to target application');
await fs.copy(path.resolve(opts.arm64AppPath, snapshotsFile.relativePath), path.resolve(tmpApp, snapshotsFile.relativePath));
}
d('moving final universal app to target destination');
await fs.mkdirp(path.dirname(opts.outAppPath));
await spawn('mv', [tmpApp, opts.outAppPath]);
}
catch (err) {
throw err;
}
finally {
await fs.remove(tmpDir);
}
};
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

1
mc_test/node_modules/@electron/universal/dist/esm/sha.d.ts generated vendored Executable file
View File

@ -0,0 +1 @@
export declare const sha: (filePath: string) => Promise<any>;

16
mc_test/node_modules/@electron/universal/dist/esm/sha.js generated vendored Executable file
View File

@ -0,0 +1,16 @@
import * as fs from 'fs-extra';
import * as crypto from 'crypto';
import { d } from './debug';
export const sha = async (filePath) => {
d('hashing', filePath);
const hash = crypto.createHash('sha256');
hash.setEncoding('hex');
const fileStream = fs.createReadStream(filePath);
fileStream.pipe(hash);
await new Promise((resolve, reject) => {
fileStream.on('end', () => resolve());
fileStream.on('error', (err) => reject(err));
});
return hash.read();
};
//# sourceMappingURL=sha.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"sha.js","sourceRoot":"","sources":["../../src/sha.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,SAAS,CAAC;AAE5B,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,QAAgB,EAAE,EAAE;IAC5C,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACvB,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACxB,MAAM,UAAU,GAAG,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACjD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACpC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QACtC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACrB,CAAC,CAAC"}