feat!: bump engines to Node.js >=22.12.0 (#139)
Some checks failed
Publish documentation / docs (push) Failing after 1m9s
Some checks failed
Publish documentation / docs (push) Failing after 1m9s
BREAKING CHANGE: Requires Node.js v22.12.0 LTS or higher. ESM-only.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`makeUniversalApp asar mode should correctly merge two identical asars 1`] = `
|
||||
exports[`makeUniversalApp > asar mode > should correctly merge two identical asars 1`] = `
|
||||
{
|
||||
"files": {
|
||||
"index.js": {
|
||||
@@ -29,7 +29,7 @@ exports[`makeUniversalApp asar mode should correctly merge two identical asars 1
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp asar mode should correctly merge two identical asars 2`] = `
|
||||
exports[`makeUniversalApp > asar mode > should correctly merge two identical asars 2`] = `
|
||||
{
|
||||
"Contents/Info.plist": {
|
||||
"Resources/app.asar": {
|
||||
@@ -40,7 +40,7 @@ exports[`makeUniversalApp asar mode should correctly merge two identical asars 2
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp asar mode should create a shim if asars are different between architectures 1`] = `
|
||||
exports[`makeUniversalApp > asar mode > should create a shim if asars are different between architectures 1`] = `
|
||||
{
|
||||
"files": {
|
||||
"extra-file.txt": {
|
||||
@@ -80,7 +80,7 @@ exports[`makeUniversalApp asar mode should create a shim if asars are different
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp asar mode should create a shim if asars are different between architectures 2`] = `
|
||||
exports[`makeUniversalApp > asar mode > should create a shim if asars are different between architectures 2`] = `
|
||||
{
|
||||
"files": {
|
||||
"index.js": {
|
||||
@@ -109,7 +109,7 @@ exports[`makeUniversalApp asar mode should create a shim if asars are different
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp asar mode should create a shim if asars are different between architectures 3`] = `
|
||||
exports[`makeUniversalApp > asar mode > should create a shim if asars are different between architectures 3`] = `
|
||||
{
|
||||
"files": {
|
||||
"index.js": {
|
||||
@@ -138,7 +138,7 @@ exports[`makeUniversalApp asar mode should create a shim if asars are different
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp asar mode should create a shim if asars are different between architectures 4`] = `
|
||||
exports[`makeUniversalApp > asar mode > should create a shim if asars are different between architectures 4`] = `
|
||||
{
|
||||
"Contents/Info.plist": {
|
||||
"Resources/app-arm64.asar": {
|
||||
@@ -157,7 +157,7 @@ exports[`makeUniversalApp asar mode should create a shim if asars are different
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp asar mode should generate AsarIntegrity for all asars in the application 1`] = `
|
||||
exports[`makeUniversalApp > asar mode > should generate AsarIntegrity for all asars in the application 1`] = `
|
||||
{
|
||||
"files": {
|
||||
"index.js": {
|
||||
@@ -215,7 +215,7 @@ exports[`makeUniversalApp asar mode should generate AsarIntegrity for all asars
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp asar mode should generate AsarIntegrity for all asars in the application 2`] = `
|
||||
exports[`makeUniversalApp > asar mode > should generate AsarIntegrity for all asars in the application 2`] = `
|
||||
{
|
||||
"files": {
|
||||
"index.js": {
|
||||
@@ -273,7 +273,7 @@ exports[`makeUniversalApp asar mode should generate AsarIntegrity for all asars
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp asar mode should generate AsarIntegrity for all asars in the application 3`] = `
|
||||
exports[`makeUniversalApp > asar mode > should generate AsarIntegrity for all asars in the application 3`] = `
|
||||
{
|
||||
"Contents/Info.plist": {
|
||||
"Resources/app.asar": {
|
||||
@@ -288,7 +288,7 @@ exports[`makeUniversalApp asar mode should generate AsarIntegrity for all asars
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp asar mode should merge two different asars when \`mergeASARs\` is enabled 1`] = `
|
||||
exports[`makeUniversalApp > asar mode > should merge two different asars when \`mergeASARs\` is enabled 1`] = `
|
||||
{
|
||||
"files": {
|
||||
"extra-file.txt": {
|
||||
@@ -328,7 +328,7 @@ exports[`makeUniversalApp asar mode should merge two different asars when \`merg
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp asar mode should merge two different asars when \`mergeASARs\` is enabled 2`] = `
|
||||
exports[`makeUniversalApp > asar mode > should merge two different asars when \`mergeASARs\` is enabled 2`] = `
|
||||
{
|
||||
"Contents/Info.plist": {
|
||||
"Resources/app.asar": {
|
||||
@@ -339,7 +339,7 @@ exports[`makeUniversalApp asar mode should merge two different asars when \`merg
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp asar mode should not inject ElectronAsarIntegrity into \`infoPlistsToIgnore\` 1`] = `
|
||||
exports[`makeUniversalApp > asar mode > should not inject ElectronAsarIntegrity into \`infoPlistsToIgnore\` 1`] = `
|
||||
{
|
||||
"files": {
|
||||
"index.js": {
|
||||
@@ -397,14 +397,14 @@ exports[`makeUniversalApp asar mode should not inject ElectronAsarIntegrity into
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp asar mode should not inject ElectronAsarIntegrity into \`infoPlistsToIgnore\` 2`] = `
|
||||
exports[`makeUniversalApp > asar mode > should not inject ElectronAsarIntegrity into \`infoPlistsToIgnore\` 2`] = `
|
||||
{
|
||||
"Contents/Info.plist": undefined,
|
||||
"Contents/Resources/SubApp-1.app/Contents/Info.plist": undefined,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp force packages successfully if \`out\` bundle already exists and \`force\` is \`true\` 1`] = `
|
||||
exports[`makeUniversalApp > force > packages successfully if \`out\` bundle already exists and \`force\` is \`true\` 1`] = `
|
||||
{
|
||||
"files": {
|
||||
"index.js": {
|
||||
@@ -433,7 +433,7 @@ exports[`makeUniversalApp force packages successfully if \`out\` bundle already
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp force packages successfully if \`out\` bundle already exists and \`force\` is \`true\` 2`] = `
|
||||
exports[`makeUniversalApp > force > packages successfully if \`out\` bundle already exists and \`force\` is \`true\` 2`] = `
|
||||
{
|
||||
"Contents/Info.plist": {
|
||||
"Resources/app.asar": {
|
||||
@@ -444,7 +444,7 @@ exports[`makeUniversalApp force packages successfully if \`out\` bundle already
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode different app dirs with different macho files (shim and lipo) 1`] = `
|
||||
exports[`makeUniversalApp > no asar mode > different app dirs with different macho files (shim and lipo) 1`] = `
|
||||
{
|
||||
"files": {
|
||||
"index.js": {
|
||||
@@ -473,13 +473,13 @@ exports[`makeUniversalApp no asar mode different app dirs with different macho f
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode different app dirs with different macho files (shim and lipo) 2`] = `
|
||||
exports[`makeUniversalApp > no asar mode > different app dirs with different macho files (shim and lipo) 2`] = `
|
||||
[
|
||||
"private/var/i-aint-got-no-rhythm.bin",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode different app dirs with different macho files (shim and lipo) 3`] = `
|
||||
exports[`makeUniversalApp > no asar mode > different app dirs with different macho files (shim and lipo) 3`] = `
|
||||
[
|
||||
"hello-world",
|
||||
"index.js",
|
||||
@@ -498,7 +498,7 @@ exports[`makeUniversalApp no asar mode different app dirs with different macho f
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode different app dirs with different macho files (shim and lipo) 4`] = `
|
||||
exports[`makeUniversalApp > no asar mode > different app dirs with different macho files (shim and lipo) 4`] = `
|
||||
[
|
||||
"hello-world",
|
||||
"index.js",
|
||||
@@ -517,7 +517,7 @@ exports[`makeUniversalApp no asar mode different app dirs with different macho f
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode different app dirs with different macho files (shim and lipo) 5`] = `
|
||||
exports[`makeUniversalApp > no asar mode > different app dirs with different macho files (shim and lipo) 5`] = `
|
||||
{
|
||||
"Contents/Info.plist": {
|
||||
"Resources/app.asar": {
|
||||
@@ -528,7 +528,7 @@ exports[`makeUniversalApp no asar mode different app dirs with different macho f
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode different app dirs with universal macho files (shim but don't lipo) 1`] = `
|
||||
exports[`makeUniversalApp > no asar mode > different app dirs with universal macho files (shim but don't lipo) 1`] = `
|
||||
{
|
||||
"files": {
|
||||
"index.js": {
|
||||
@@ -557,13 +557,13 @@ exports[`makeUniversalApp no asar mode different app dirs with universal macho f
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode different app dirs with universal macho files (shim but don't lipo) 2`] = `
|
||||
exports[`makeUniversalApp > no asar mode > different app dirs with universal macho files (shim but don't lipo) 2`] = `
|
||||
[
|
||||
"private/var/i-aint-got-no-rhythm.bin",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode different app dirs with universal macho files (shim but don't lipo) 3`] = `
|
||||
exports[`makeUniversalApp > no asar mode > different app dirs with universal macho files (shim but don't lipo) 3`] = `
|
||||
[
|
||||
"hello-world",
|
||||
"index.js",
|
||||
@@ -582,7 +582,7 @@ exports[`makeUniversalApp no asar mode different app dirs with universal macho f
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode different app dirs with universal macho files (shim but don't lipo) 4`] = `
|
||||
exports[`makeUniversalApp > no asar mode > different app dirs with universal macho files (shim but don't lipo) 4`] = `
|
||||
[
|
||||
"hello-world",
|
||||
"index.js",
|
||||
@@ -601,7 +601,7 @@ exports[`makeUniversalApp no asar mode different app dirs with universal macho f
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode different app dirs with universal macho files (shim but don't lipo) 5`] = `
|
||||
exports[`makeUniversalApp > no asar mode > different app dirs with universal macho files (shim but don't lipo) 5`] = `
|
||||
{
|
||||
"Contents/Info.plist": {
|
||||
"Resources/app.asar": {
|
||||
@@ -612,7 +612,7 @@ exports[`makeUniversalApp no asar mode different app dirs with universal macho f
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode identical app dirs with different macho files (e.g. do not shim, but still lipo) 1`] = `
|
||||
exports[`makeUniversalApp > no asar mode > identical app dirs with different macho files (e.g. do not shim, but still lipo) 1`] = `
|
||||
[
|
||||
"hello-world",
|
||||
"index.js",
|
||||
@@ -630,13 +630,13 @@ exports[`makeUniversalApp no asar mode identical app dirs with different macho f
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode identical app dirs with different macho files (e.g. do not shim, but still lipo) 2`] = `
|
||||
exports[`makeUniversalApp > no asar mode > identical app dirs with different macho files (e.g. do not shim, but still lipo) 2`] = `
|
||||
{
|
||||
"Contents/Info.plist": {},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode identical app dirs with universal macho files (e.g., do not shim, just copy x64 dir) 1`] = `
|
||||
exports[`makeUniversalApp > no asar mode > identical app dirs with universal macho files (e.g., do not shim, just copy x64 dir) 1`] = `
|
||||
[
|
||||
"hello-world",
|
||||
"index.js",
|
||||
@@ -654,13 +654,13 @@ exports[`makeUniversalApp no asar mode identical app dirs with universal macho f
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode identical app dirs with universal macho files (e.g., do not shim, just copy x64 dir) 2`] = `
|
||||
exports[`makeUniversalApp > no asar mode > identical app dirs with universal macho files (e.g., do not shim, just copy x64 dir) 2`] = `
|
||||
{
|
||||
"Contents/Info.plist": {},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode should correctly merge two identical app folders 1`] = `
|
||||
exports[`makeUniversalApp > no asar mode > should correctly merge two identical app folders 1`] = `
|
||||
[
|
||||
"index.js",
|
||||
{
|
||||
@@ -673,13 +673,13 @@ exports[`makeUniversalApp no asar mode should correctly merge two identical app
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode should correctly merge two identical app folders 2`] = `
|
||||
exports[`makeUniversalApp > no asar mode > should correctly merge two identical app folders 2`] = `
|
||||
{
|
||||
"Contents/Info.plist": {},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode should shim two different app folders 1`] = `
|
||||
exports[`makeUniversalApp > no asar mode > should shim two different app folders 1`] = `
|
||||
{
|
||||
"files": {
|
||||
"index.js": {
|
||||
@@ -708,13 +708,13 @@ exports[`makeUniversalApp no asar mode should shim two different app folders 1`]
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode should shim two different app folders 2`] = `
|
||||
exports[`makeUniversalApp > no asar mode > should shim two different app folders 2`] = `
|
||||
[
|
||||
"private/var/i-aint-got-no-rhythm.bin",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode should shim two different app folders 3`] = `
|
||||
exports[`makeUniversalApp > no asar mode > should shim two different app folders 3`] = `
|
||||
[
|
||||
"index.js",
|
||||
{
|
||||
@@ -732,7 +732,7 @@ exports[`makeUniversalApp no asar mode should shim two different app folders 3`]
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode should shim two different app folders 4`] = `
|
||||
exports[`makeUniversalApp > no asar mode > should shim two different app folders 4`] = `
|
||||
[
|
||||
"index.js",
|
||||
{
|
||||
@@ -750,7 +750,7 @@ exports[`makeUniversalApp no asar mode should shim two different app folders 4`]
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp no asar mode should shim two different app folders 5`] = `
|
||||
exports[`makeUniversalApp > no asar mode > should shim two different app folders 5`] = `
|
||||
{
|
||||
"Contents/Info.plist": {
|
||||
"Resources/app.asar": {
|
||||
@@ -761,7 +761,7 @@ exports[`makeUniversalApp no asar mode should shim two different app folders 5`]
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp works for lipo binary resources 1`] = `
|
||||
exports[`makeUniversalApp > works for lipo binary resources 1`] = `
|
||||
{
|
||||
"files": {
|
||||
"hello-world": "<stripped>",
|
||||
@@ -820,15 +820,15 @@ exports[`makeUniversalApp works for lipo binary resources 1`] = `
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp works for lipo binary resources 2`] = `[]`;
|
||||
exports[`makeUniversalApp > works for lipo binary resources 2`] = `[]`;
|
||||
|
||||
exports[`makeUniversalApp works for lipo binary resources 3`] = `
|
||||
exports[`makeUniversalApp > works for lipo binary resources 3`] = `
|
||||
[
|
||||
"hello-world",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`makeUniversalApp works for lipo binary resources 4`] = `
|
||||
exports[`makeUniversalApp > works for lipo binary resources 4`] = `
|
||||
{
|
||||
"Contents/Info.plist": {
|
||||
"Resources/app.asar": {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import * as path from 'path';
|
||||
import * as path from 'node:path';
|
||||
|
||||
import { AsarMode, detectAsarMode, generateAsarIntegrity } from '../src/asar-utils';
|
||||
import { describe, expect, it } from '@jest/globals';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
const asarsPath = path.resolve(__dirname, 'fixtures', 'asars');
|
||||
const appsPath = path.resolve(__dirname, 'fixtures', 'apps');
|
||||
import { AsarMode, detectAsarMode, generateAsarIntegrity } from '../src/asar-utils.js';
|
||||
|
||||
const asarsPath = path.resolve(import.meta.dirname, 'fixtures', 'asars');
|
||||
const appsPath = path.resolve(import.meta.dirname, 'fixtures', 'apps');
|
||||
|
||||
describe('asar-utils', () => {
|
||||
describe('detectAsarMode', () => {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import * as path from 'path';
|
||||
import * as path from 'node:path';
|
||||
|
||||
import { AppFile, AppFileType, getAllAppFiles } from '../src/file-utils';
|
||||
import { beforeAll, describe, expect, it } from '@jest/globals';
|
||||
import { beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
const appsPath = path.resolve(__dirname, 'fixtures', 'apps');
|
||||
import { AppFile, AppFileType, getAllAppFiles } from '../src/file-utils.js';
|
||||
|
||||
const appsPath = path.resolve(import.meta.dirname, 'fixtures', 'apps');
|
||||
|
||||
describe('file-utils', () => {
|
||||
describe('getAllAppFiles', () => {
|
||||
|
||||
82
test/globalSetup.ts
Normal file
82
test/globalSetup.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { appsDir, asarsDir, fixtureDir, templateApp } from './util.js';
|
||||
|
||||
// generates binaries from hello-world.c
|
||||
// hello-world-universal, hello-world-x86_64, hello-world-arm64
|
||||
const generateMachO = () => {
|
||||
const src = path.resolve(fixtureDir, 'hello-world.c');
|
||||
|
||||
const outputFiles = ['x86_64', 'arm64'].map((arch) => {
|
||||
const machO = path.resolve(appsDir, `hello-world-${arch === 'x86_64' ? 'x64' : arch}`);
|
||||
execFileSync('clang', ['-arch', arch, '-o', machO, src]);
|
||||
return machO;
|
||||
});
|
||||
|
||||
execFileSync('lipo', [
|
||||
...outputFiles,
|
||||
'-create',
|
||||
'-output',
|
||||
path.resolve(appsDir, 'hello-world-universal'),
|
||||
]);
|
||||
};
|
||||
|
||||
export default async () => {
|
||||
await fs.promises.rm(appsDir, { recursive: true, force: true });
|
||||
await fs.promises.mkdir(appsDir, { recursive: true });
|
||||
|
||||
// generate mach-o binaries to be leveraged in lipo tests
|
||||
generateMachO();
|
||||
|
||||
await templateApp('Arm64Asar.app', 'arm64', async (appPath) => {
|
||||
await fs.promises.cp(
|
||||
path.resolve(asarsDir, 'app.asar'),
|
||||
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
|
||||
{ recursive: true, verbatimSymlinks: true },
|
||||
);
|
||||
});
|
||||
|
||||
// contains `extra-file.txt`
|
||||
await templateApp('Arm64AsarExtraFile.app', 'arm64', async (appPath) => {
|
||||
await fs.promises.cp(
|
||||
path.resolve(asarsDir, 'app2.asar'),
|
||||
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
|
||||
{ recursive: true, verbatimSymlinks: true },
|
||||
);
|
||||
});
|
||||
|
||||
await templateApp('X64Asar.app', 'x64', async (appPath) => {
|
||||
await fs.promises.cp(
|
||||
path.resolve(asarsDir, 'app.asar'),
|
||||
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
|
||||
{ recursive: true, verbatimSymlinks: true },
|
||||
);
|
||||
});
|
||||
|
||||
await templateApp('Arm64NoAsar.app', 'arm64', async (appPath) => {
|
||||
await fs.promises.cp(
|
||||
path.resolve(asarsDir, 'app'),
|
||||
path.resolve(appPath, 'Contents', 'Resources', 'app'),
|
||||
{ recursive: true, verbatimSymlinks: true },
|
||||
);
|
||||
});
|
||||
|
||||
// contains `extra-file.txt`
|
||||
await templateApp('Arm64NoAsarExtraFile.app', 'arm64', async (appPath) => {
|
||||
await fs.promises.cp(
|
||||
path.resolve(asarsDir, 'app2'),
|
||||
path.resolve(appPath, 'Contents', 'Resources', 'app'),
|
||||
{ recursive: true, verbatimSymlinks: true },
|
||||
);
|
||||
});
|
||||
|
||||
await templateApp('X64NoAsar.app', 'x64', async (appPath) => {
|
||||
await fs.promises.cp(
|
||||
path.resolve(asarsDir, 'app'),
|
||||
path.resolve(appPath, 'Contents', 'Resources', 'app'),
|
||||
{ recursive: true, verbatimSymlinks: true },
|
||||
);
|
||||
});
|
||||
};
|
||||
@@ -1,24 +1,27 @@
|
||||
import * as fs from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { makeUniversalApp } from '../dist/cjs/index';
|
||||
import { afterEach, describe, expect, it } from 'vitest';
|
||||
|
||||
import { makeUniversalApp } from '../dist/index.js';
|
||||
import { fsMove } from '../src/file-utils.js';
|
||||
import {
|
||||
createStagingAppDir,
|
||||
generateNativeApp,
|
||||
templateApp,
|
||||
VERIFY_APP_TIMEOUT,
|
||||
verifyApp,
|
||||
} from './util';
|
||||
} from './util.js';
|
||||
import { createPackage, createPackageWithOptions } from '@electron/asar';
|
||||
import { afterEach, describe, expect, it } from '@jest/globals';
|
||||
|
||||
const appsPath = path.resolve(__dirname, 'fixtures', 'apps');
|
||||
const appsOutPath = path.resolve(__dirname, 'fixtures', 'apps', 'out');
|
||||
const appsPath = path.resolve(import.meta.dirname, 'fixtures', 'apps');
|
||||
const appsOutPath = path.resolve(import.meta.dirname, 'fixtures', 'apps', 'out');
|
||||
|
||||
// See `jest.setup.ts` for app fixture setup process
|
||||
// See `globalSetup.ts` for app fixture setup process
|
||||
describe('makeUniversalApp', () => {
|
||||
afterEach(async () => {
|
||||
await fs.emptyDir(appsOutPath);
|
||||
await fs.promises.rm(appsOutPath, { force: true, recursive: true });
|
||||
await fs.promises.mkdir(appsOutPath, { recursive: true });
|
||||
});
|
||||
|
||||
it('throws an error if asar is only detected in one arch', async () => {
|
||||
@@ -34,31 +37,27 @@ describe('makeUniversalApp', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it(
|
||||
'works for lipo binary resources',
|
||||
async () => {
|
||||
const x64AppPath = await generateNativeApp({
|
||||
appNameWithExtension: 'LipoX64.app',
|
||||
arch: 'x64',
|
||||
createAsar: true,
|
||||
});
|
||||
const arm64AppPath = await generateNativeApp({
|
||||
appNameWithExtension: 'LipoArm64.app',
|
||||
arch: 'arm64',
|
||||
createAsar: true,
|
||||
});
|
||||
it('works for lipo binary resources', { timeout: VERIFY_APP_TIMEOUT }, async () => {
|
||||
const x64AppPath = await generateNativeApp({
|
||||
appNameWithExtension: 'LipoX64.app',
|
||||
arch: 'x64',
|
||||
createAsar: true,
|
||||
});
|
||||
const arm64AppPath = await generateNativeApp({
|
||||
appNameWithExtension: 'LipoArm64.app',
|
||||
arch: 'arm64',
|
||||
createAsar: true,
|
||||
});
|
||||
|
||||
const out = path.resolve(appsOutPath, 'Lipo.app');
|
||||
await makeUniversalApp({ x64AppPath, arm64AppPath, outAppPath: out, mergeASARs: true });
|
||||
await verifyApp(out, true);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
const out = path.resolve(appsOutPath, 'Lipo.app');
|
||||
await makeUniversalApp({ x64AppPath, arm64AppPath, outAppPath: out, mergeASARs: true });
|
||||
await verifyApp(out, true);
|
||||
});
|
||||
|
||||
describe('force', () => {
|
||||
it('throws an error if `out` bundle already exists and `force` is `false`', async () => {
|
||||
const out = path.resolve(appsOutPath, 'Error.app');
|
||||
await fs.mkdirp(out);
|
||||
await fs.promises.mkdir(out, { recursive: true });
|
||||
await expect(
|
||||
makeUniversalApp({
|
||||
x64AppPath: path.resolve(appsPath, 'X64Asar.app'),
|
||||
@@ -70,9 +69,10 @@ describe('makeUniversalApp', () => {
|
||||
|
||||
it(
|
||||
'packages successfully if `out` bundle already exists and `force` is `true`',
|
||||
{ timeout: VERIFY_APP_TIMEOUT },
|
||||
async () => {
|
||||
const out = path.resolve(appsOutPath, 'NoError.app');
|
||||
await fs.mkdirp(out);
|
||||
await fs.promises.mkdir(out, { recursive: true });
|
||||
await makeUniversalApp({
|
||||
x64AppPath: path.resolve(appsPath, 'X64Asar.app'),
|
||||
arm64AppPath: path.resolve(appsPath, 'Arm64Asar.app'),
|
||||
@@ -81,27 +81,23 @@ describe('makeUniversalApp', () => {
|
||||
});
|
||||
await verifyApp(out);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
});
|
||||
|
||||
describe('asar mode', () => {
|
||||
it(
|
||||
'should correctly merge two identical asars',
|
||||
async () => {
|
||||
const out = path.resolve(appsOutPath, 'MergedAsar.app');
|
||||
await makeUniversalApp({
|
||||
x64AppPath: path.resolve(appsPath, 'X64Asar.app'),
|
||||
arm64AppPath: path.resolve(appsPath, 'Arm64Asar.app'),
|
||||
outAppPath: out,
|
||||
});
|
||||
await verifyApp(out);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
it('should correctly merge two identical asars', { timeout: VERIFY_APP_TIMEOUT }, async () => {
|
||||
const out = path.resolve(appsOutPath, 'MergedAsar.app');
|
||||
await makeUniversalApp({
|
||||
x64AppPath: path.resolve(appsPath, 'X64Asar.app'),
|
||||
arm64AppPath: path.resolve(appsPath, 'Arm64Asar.app'),
|
||||
outAppPath: out,
|
||||
});
|
||||
await verifyApp(out);
|
||||
});
|
||||
|
||||
it(
|
||||
'should create a shim if asars are different between architectures',
|
||||
{ timeout: VERIFY_APP_TIMEOUT },
|
||||
async () => {
|
||||
const out = path.resolve(appsOutPath, 'ShimmedAsar.app');
|
||||
await makeUniversalApp({
|
||||
@@ -111,11 +107,11 @@ describe('makeUniversalApp', () => {
|
||||
});
|
||||
await verifyApp(out);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
|
||||
it(
|
||||
'should merge two different asars when `mergeASARs` is enabled',
|
||||
{ timeout: VERIFY_APP_TIMEOUT },
|
||||
async () => {
|
||||
const out = path.resolve(appsOutPath, 'MergedAsar.app');
|
||||
await makeUniversalApp({
|
||||
@@ -127,11 +123,11 @@ describe('makeUniversalApp', () => {
|
||||
});
|
||||
await verifyApp(out);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
|
||||
it(
|
||||
'throws an error if `mergeASARs` is enabled and `singleArchFiles` is missing a unique file',
|
||||
{ timeout: VERIFY_APP_TIMEOUT },
|
||||
async () => {
|
||||
const out = path.resolve(appsOutPath, 'Error.app');
|
||||
await expect(
|
||||
@@ -144,17 +140,17 @@ describe('makeUniversalApp', () => {
|
||||
}),
|
||||
).rejects.toThrow(/Detected unique file "extra-file\.txt"/);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
|
||||
it(
|
||||
'should not inject ElectronAsarIntegrity into `infoPlistsToIgnore`',
|
||||
{ timeout: VERIFY_APP_TIMEOUT },
|
||||
async () => {
|
||||
const arm64AppPath = await templateApp('Arm64-1.app', 'arm64', async (appPath) => {
|
||||
const { testPath } = await createStagingAppDir('Arm64-1');
|
||||
await createPackage(testPath, path.resolve(appPath, 'Contents', 'Resources', 'app.asar'));
|
||||
await templateApp('SubApp-1.app', 'arm64', async (subArm64AppPath) => {
|
||||
await fs.move(
|
||||
await fsMove(
|
||||
subArm64AppPath,
|
||||
path.resolve(appPath, 'Contents', 'Resources', path.basename(subArm64AppPath)),
|
||||
);
|
||||
@@ -164,7 +160,7 @@ describe('makeUniversalApp', () => {
|
||||
const { testPath } = await createStagingAppDir('X64-1');
|
||||
await createPackage(testPath, path.resolve(appPath, 'Contents', 'Resources', 'app.asar'));
|
||||
await templateApp('SubApp-1.app', 'x64', async (subArm64AppPath) => {
|
||||
await fs.move(
|
||||
await fsMove(
|
||||
subArm64AppPath,
|
||||
path.resolve(appPath, 'Contents', 'Resources', path.basename(subArm64AppPath)),
|
||||
);
|
||||
@@ -180,7 +176,6 @@ describe('makeUniversalApp', () => {
|
||||
});
|
||||
await verifyApp(outAppPath);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
|
||||
// TODO: Investigate if this should even be allowed.
|
||||
@@ -188,6 +183,7 @@ describe('makeUniversalApp', () => {
|
||||
// https://github.com/electron/universal/blob/d90d573ccf69a5b14b91aa818c8b97e0e6840399/src/file-utils.ts#L48-L49
|
||||
it.skip(
|
||||
'should shim asars with different unpacked dirs',
|
||||
{ timeout: VERIFY_APP_TIMEOUT },
|
||||
async () => {
|
||||
const arm64AppPath = await templateApp('UnpackedArm64.app', 'arm64', async (appPath) => {
|
||||
const { testPath } = await createStagingAppDir('UnpackedAppArm64');
|
||||
@@ -218,32 +214,32 @@ describe('makeUniversalApp', () => {
|
||||
});
|
||||
await verifyApp(outAppPath);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
|
||||
it(
|
||||
'should generate AsarIntegrity for all asars in the application',
|
||||
{ timeout: VERIFY_APP_TIMEOUT },
|
||||
async () => {
|
||||
const { testPath } = await createStagingAppDir('app-2');
|
||||
const testAsarPath = path.resolve(appsOutPath, 'app-2.asar');
|
||||
await createPackage(testPath, testAsarPath);
|
||||
|
||||
const arm64AppPath = await templateApp('Arm64-2.app', 'arm64', async (appPath) => {
|
||||
await fs.copyFile(
|
||||
await fs.promises.copyFile(
|
||||
testAsarPath,
|
||||
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
|
||||
);
|
||||
await fs.copyFile(
|
||||
await fs.promises.copyFile(
|
||||
testAsarPath,
|
||||
path.resolve(appPath, 'Contents', 'Resources', 'webapp.asar'),
|
||||
);
|
||||
});
|
||||
const x64AppPath = await templateApp('X64-2.app', 'x64', async (appPath) => {
|
||||
await fs.copyFile(
|
||||
await fs.promises.copyFile(
|
||||
testAsarPath,
|
||||
path.resolve(appPath, 'Contents', 'Resources', 'app.asar'),
|
||||
);
|
||||
await fs.copyFile(
|
||||
await fs.promises.copyFile(
|
||||
testAsarPath,
|
||||
path.resolve(appPath, 'Contents', 'Resources', 'webbapp.asar'),
|
||||
);
|
||||
@@ -257,13 +253,13 @@ describe('makeUniversalApp', () => {
|
||||
});
|
||||
await verifyApp(outAppPath);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
});
|
||||
|
||||
describe('no asar mode', () => {
|
||||
it(
|
||||
'should correctly merge two identical app folders',
|
||||
{ timeout: VERIFY_APP_TIMEOUT },
|
||||
async () => {
|
||||
const out = path.resolve(appsOutPath, 'MergedNoAsar.app');
|
||||
await makeUniversalApp({
|
||||
@@ -273,39 +269,41 @@ describe('makeUniversalApp', () => {
|
||||
});
|
||||
await verifyApp(out);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
|
||||
it(
|
||||
'should shim two different app folders',
|
||||
async () => {
|
||||
const arm64AppPath = await templateApp('ShimArm64.app', 'arm64', async (appPath) => {
|
||||
const { testPath } = await createStagingAppDir('shimArm64', {
|
||||
'i-aint-got-no-rhythm.bin': 'boomshakalaka',
|
||||
});
|
||||
await fs.copy(testPath, path.resolve(appPath, 'Contents', 'Resources', 'app'));
|
||||
it('should shim two different app folders', { timeout: VERIFY_APP_TIMEOUT }, async () => {
|
||||
const arm64AppPath = await templateApp('ShimArm64.app', 'arm64', async (appPath) => {
|
||||
const { testPath } = await createStagingAppDir('shimArm64', {
|
||||
'i-aint-got-no-rhythm.bin': 'boomshakalaka',
|
||||
});
|
||||
await fs.promises.cp(testPath, path.resolve(appPath, 'Contents', 'Resources', 'app'), {
|
||||
recursive: true,
|
||||
verbatimSymlinks: true,
|
||||
});
|
||||
});
|
||||
|
||||
const x64AppPath = await templateApp('ShimX64.app', 'x64', async (appPath) => {
|
||||
const { testPath } = await createStagingAppDir('shimX64', {
|
||||
'hello-world.bin': 'Hello World',
|
||||
});
|
||||
await fs.copy(testPath, path.resolve(appPath, 'Contents', 'Resources', 'app'));
|
||||
const x64AppPath = await templateApp('ShimX64.app', 'x64', async (appPath) => {
|
||||
const { testPath } = await createStagingAppDir('shimX64', {
|
||||
'hello-world.bin': 'Hello World',
|
||||
});
|
||||
await fs.promises.cp(testPath, path.resolve(appPath, 'Contents', 'Resources', 'app'), {
|
||||
recursive: true,
|
||||
verbatimSymlinks: true,
|
||||
});
|
||||
});
|
||||
|
||||
const outAppPath = path.resolve(appsOutPath, 'ShimNoAsar.app');
|
||||
await makeUniversalApp({
|
||||
x64AppPath,
|
||||
arm64AppPath,
|
||||
outAppPath,
|
||||
});
|
||||
await verifyApp(outAppPath);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
const outAppPath = path.resolve(appsOutPath, 'ShimNoAsar.app');
|
||||
await makeUniversalApp({
|
||||
x64AppPath,
|
||||
arm64AppPath,
|
||||
outAppPath,
|
||||
});
|
||||
await verifyApp(outAppPath);
|
||||
});
|
||||
|
||||
it(
|
||||
'different app dirs with different macho files (shim and lipo)',
|
||||
{ timeout: VERIFY_APP_TIMEOUT },
|
||||
async () => {
|
||||
const x64AppPath = await generateNativeApp({
|
||||
appNameWithExtension: 'DifferentMachoAppX64-1.app',
|
||||
@@ -332,11 +330,11 @@ describe('makeUniversalApp', () => {
|
||||
});
|
||||
await verifyApp(outAppPath, true);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
|
||||
it(
|
||||
"different app dirs with universal macho files (shim but don't lipo)",
|
||||
{ timeout: VERIFY_APP_TIMEOUT },
|
||||
async () => {
|
||||
const x64AppPath = await generateNativeApp({
|
||||
appNameWithExtension: 'DifferentButUniversalMachoAppX64-2.app',
|
||||
@@ -365,11 +363,11 @@ describe('makeUniversalApp', () => {
|
||||
});
|
||||
await verifyApp(outAppPath, true);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
|
||||
it(
|
||||
'identical app dirs with different macho files (e.g. do not shim, but still lipo)',
|
||||
{ timeout: VERIFY_APP_TIMEOUT },
|
||||
async () => {
|
||||
const x64AppPath = await generateNativeApp({
|
||||
appNameWithExtension: 'DifferentMachoAppX64-2.app',
|
||||
@@ -390,11 +388,11 @@ describe('makeUniversalApp', () => {
|
||||
});
|
||||
await verifyApp(out, true);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
|
||||
it(
|
||||
'identical app dirs with universal macho files (e.g., do not shim, just copy x64 dir)',
|
||||
{ timeout: VERIFY_APP_TIMEOUT },
|
||||
async () => {
|
||||
const x64AppPath = await generateNativeApp({
|
||||
appNameWithExtension: 'UniversalMachoAppX64.app',
|
||||
@@ -413,7 +411,6 @@ describe('makeUniversalApp', () => {
|
||||
await makeUniversalApp({ x64AppPath, arm64AppPath, outAppPath: out });
|
||||
await verifyApp(out, true);
|
||||
},
|
||||
VERIFY_APP_TIMEOUT,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import * as path from 'path';
|
||||
import path from 'node:path';
|
||||
|
||||
import { sha } from '../src/sha';
|
||||
import { describe, expect, it } from '@jest/globals';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { sha } from '../src/sha.js';
|
||||
|
||||
describe('sha', () => {
|
||||
it('should correctly hash a file', async () => {
|
||||
expect(await sha(path.resolve(__dirname, 'fixtures', 'tohash'))).toEqual(
|
||||
expect(await sha(path.resolve(import.meta.dirname, 'fixtures', 'tohash'))).toEqual(
|
||||
'12998c017066eb0d2a70b94e6ed3192985855ce390f321bbdb832022888bd251',
|
||||
);
|
||||
});
|
||||
|
||||
53
test/util.ts
53
test/util.ts
@@ -1,29 +1,31 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { createPackageWithOptions, getRawHeader } from '@electron/asar';
|
||||
import { downloadArtifact } from '@electron/get';
|
||||
import { spawn } from '@malept/cross-spawn-promise';
|
||||
import * as zip from 'cross-zip';
|
||||
import * as fs from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
import plist from 'plist';
|
||||
import * as fileUtils from '../dist/cjs/file-utils';
|
||||
import { createPackageWithOptions, getRawHeader } from '@electron/asar';
|
||||
|
||||
declare const expect: typeof import('@jest/globals').expect;
|
||||
import * as fileUtils from '../dist/file-utils.js';
|
||||
|
||||
// We do a LOT of verifications in `verifyApp` 😅
|
||||
// exec universal binary -> verify ALL asars -> verify ALL app dirs -> verify ALL asar integrity entries
|
||||
// plus some tests create fixtures at runtime
|
||||
export const VERIFY_APP_TIMEOUT = 80 * 1000;
|
||||
|
||||
export const fixtureDir = path.resolve(__dirname, 'fixtures');
|
||||
export const fixtureDir = path.resolve(import.meta.dirname, 'fixtures');
|
||||
export const asarsDir = path.resolve(fixtureDir, 'asars');
|
||||
export const appsDir = path.resolve(fixtureDir, 'apps');
|
||||
export const appsOutPath = path.resolve(appsDir, 'out');
|
||||
|
||||
export const verifyApp = async (appPath: string, containsRuntimeGeneratedMacho = false) => {
|
||||
const { expect } = await import('vitest');
|
||||
|
||||
await ensureUniversal(appPath);
|
||||
|
||||
const resourcesDir = path.resolve(appPath, 'Contents', 'Resources');
|
||||
const resourcesDirContents = await fs.readdir(resourcesDir);
|
||||
const resourcesDirContents = await fs.promises.readdir(resourcesDir);
|
||||
|
||||
// sort for consistent result
|
||||
const asars = resourcesDirContents.filter((p) => p.endsWith('.asar')).sort();
|
||||
@@ -79,12 +81,14 @@ export const verifyApp = async (appPath: string, containsRuntimeGeneratedMacho =
|
||||
|
||||
const extractAsarIntegrity = async (infoPlist: string) => {
|
||||
const { ElectronAsarIntegrity: integrity, ...otherData } = plist.parse(
|
||||
await fs.readFile(infoPlist, 'utf-8'),
|
||||
await fs.promises.readFile(infoPlist, 'utf-8'),
|
||||
) as any;
|
||||
return integrity;
|
||||
};
|
||||
|
||||
export const verifyFileTree = async (dirPath: string) => {
|
||||
const { expect } = await import('vitest');
|
||||
|
||||
const dirFiles = await fileUtils.getAllAppFiles(dirPath);
|
||||
const files = dirFiles.map((file) => {
|
||||
const it = path.join(dirPath, file.relativePath);
|
||||
@@ -98,6 +102,8 @@ export const verifyFileTree = async (dirPath: string) => {
|
||||
};
|
||||
|
||||
export const ensureUniversal = async (app: string) => {
|
||||
const { expect } = await import('vitest');
|
||||
|
||||
const exe = path.resolve(app, 'Contents', 'MacOS', 'Electron');
|
||||
const result = await spawn(exe);
|
||||
expect(result).toContain('arm64');
|
||||
@@ -162,15 +168,18 @@ export const createStagingAppDir = async (
|
||||
) => {
|
||||
const outDir = (testName || 'app') + Math.floor(Math.random() * 100); // tests run in parallel, randomize dir suffix to prevent naming collisions
|
||||
const testPath = path.join(appsDir, outDir);
|
||||
await fs.remove(testPath);
|
||||
await fs.promises.rm(testPath, { recursive: true, force: true });
|
||||
|
||||
await fs.copy(path.join(asarsDir, 'app'), testPath);
|
||||
await fs.promises.cp(path.join(asarsDir, 'app'), testPath, {
|
||||
recursive: true,
|
||||
verbatimSymlinks: true,
|
||||
});
|
||||
|
||||
const privateVarPath = path.join(testPath, 'private', 'var');
|
||||
const varPath = path.join(testPath, 'var');
|
||||
|
||||
await fs.mkdir(privateVarPath, { recursive: true });
|
||||
await fs.symlink(path.relative(testPath, privateVarPath), varPath);
|
||||
await fs.promises.mkdir(privateVarPath, { recursive: true });
|
||||
await fs.promises.symlink(path.relative(testPath, privateVarPath), varPath);
|
||||
|
||||
const files = {
|
||||
'file.txt': 'hello world',
|
||||
@@ -178,11 +187,11 @@ export const createStagingAppDir = async (
|
||||
};
|
||||
for await (const [filename, fileData] of Object.entries(files)) {
|
||||
const originFilePath = path.join(varPath, filename);
|
||||
await fs.writeFile(originFilePath, fileData);
|
||||
await fs.promises.writeFile(originFilePath, fileData);
|
||||
}
|
||||
const appPath = path.join(varPath, 'app');
|
||||
await fs.mkdirp(appPath);
|
||||
await fs.symlink('../file.txt', path.join(appPath, 'file.txt'));
|
||||
await fs.promises.mkdir(appPath, { recursive: true });
|
||||
await fs.promises.symlink('../file.txt', path.join(appPath, 'file.txt'));
|
||||
|
||||
return {
|
||||
testPath,
|
||||
@@ -204,8 +213,11 @@ export const templateApp = async (
|
||||
});
|
||||
const appPath = path.resolve(appsDir, name);
|
||||
zip.unzipSync(electronZip, appsDir);
|
||||
await fs.rename(path.resolve(appsDir, 'Electron.app'), appPath);
|
||||
await fs.remove(path.resolve(appPath, 'Contents', 'Resources', 'default_app.asar'));
|
||||
await fs.promises.rename(path.resolve(appsDir, 'Electron.app'), appPath);
|
||||
await fs.promises.rm(path.resolve(appPath, 'Contents', 'Resources', 'default_app.asar'), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
await modify(appPath);
|
||||
|
||||
return appPath;
|
||||
@@ -229,22 +241,23 @@ export const generateNativeApp = async (options: {
|
||||
const resources = path.join(appPath, 'Contents', 'Resources');
|
||||
const resourcesApp = path.resolve(resources, 'app');
|
||||
if (!fs.existsSync(resourcesApp)) {
|
||||
await fs.mkdir(resourcesApp);
|
||||
await fs.promises.mkdir(resourcesApp, { recursive: true });
|
||||
}
|
||||
const { testPath } = await createStagingAppDir(
|
||||
path.basename(appNameWithExtension, '.app'),
|
||||
additionalFiles,
|
||||
);
|
||||
await fs.copy(
|
||||
await fs.promises.cp(
|
||||
path.join(appsDir, `hello-world-${nativeModuleArch}`),
|
||||
path.join(testPath, 'hello-world'),
|
||||
{ recursive: true, verbatimSymlinks: true },
|
||||
);
|
||||
if (createAsar) {
|
||||
await createPackageWithOptions(testPath, path.resolve(resources, 'app.asar'), {
|
||||
unpack: '**/hello-world',
|
||||
});
|
||||
} else {
|
||||
await fs.copy(testPath, resourcesApp);
|
||||
await fs.promises.cp(testPath, resourcesApp, { recursive: true, verbatimSymlinks: true });
|
||||
}
|
||||
});
|
||||
return appPath;
|
||||
|
||||
Reference in New Issue
Block a user