electron-packager
Advanced tools
| 'use strict' | ||
| const universal = require('@electron/universal') | ||
| const common = require('./common') | ||
| const fs = require('fs-extra') | ||
| const path = require('path') | ||
| async function packageUniversalMac (packageForPlatformAndArchWithOpts, buildDir, comboOpts, downloadOpts, tempBase) { | ||
| // In order to generate a universal macOS build we actually need to build the x64 and the arm64 app | ||
| // and then glue them together | ||
| common.info(`Packaging app for platform ${comboOpts.platform} universal using electron v${comboOpts.electronVersion} - Building x64 and arm64 slices now`, comboOpts.quiet) | ||
| await fs.mkdirp(tempBase) | ||
| const tempDir = await fs.mkdtemp(path.resolve(tempBase, 'electron-packager-universal-')) | ||
| const { App } = require('./mac') | ||
| const app = new App(comboOpts, buildDir) | ||
| const universalStagingPath = app.stagingPath | ||
| const finalUniversalPath = common.generateFinalPath(app.opts) | ||
| if (await fs.pathExists(finalUniversalPath)) { | ||
| if (comboOpts.overwrite) { | ||
| await fs.remove(finalUniversalPath) | ||
| } else { | ||
| common.info(`Skipping ${comboOpts.platform} ${comboOpts.arch} (output dir already exists, use --overwrite to force)`, comboOpts.quiet) | ||
| return true | ||
| } | ||
| } | ||
| const [x64AppPath, arm64AppPath] = await Promise.all(['x64', 'arm64'].map((tempArch) => { | ||
| const tempOpts = { | ||
| ...comboOpts, | ||
| arch: tempArch, | ||
| out: tempDir | ||
| } | ||
| const tempDownloadOpts = { | ||
| ...downloadOpts, | ||
| arch: tempArch | ||
| } | ||
| // Do not sign or notarize the individual slices, we sign and notarize the merged app later | ||
| delete tempOpts.osxSign | ||
| delete tempOpts.osxNotarize | ||
| return packageForPlatformAndArchWithOpts(tempOpts, tempDownloadOpts) | ||
| })) | ||
| common.info(`Stitching universal app for platform ${comboOpts.platform}`, comboOpts.quiet) | ||
| const generatedFiles = await fs.readdir(x64AppPath) | ||
| const appName = generatedFiles.filter(file => path.extname(file) === '.app')[0] | ||
| await universal.makeUniversalApp({ | ||
| ...comboOpts.osxUniversal, | ||
| x64AppPath: path.resolve(x64AppPath, appName), | ||
| arm64AppPath: path.resolve(arm64AppPath, appName), | ||
| outAppPath: path.resolve(universalStagingPath, appName) | ||
| }) | ||
| await app.signAppIfSpecified() | ||
| await app.notarizeAppIfSpecified() | ||
| await app.move() | ||
| for (const generatedFile of generatedFiles) { | ||
| if (path.extname(generatedFile) === '.app') continue | ||
| await fs.copy(path.resolve(x64AppPath, generatedFile), path.resolve(finalUniversalPath, generatedFile)) | ||
| } | ||
| await fs.remove(tempDir) | ||
| return finalUniversalPath | ||
| } | ||
| module.exports = { | ||
| packageUniversalMac | ||
| } |
+9
-0
@@ -7,2 +7,11 @@ # Electron Packager: Changes by Version | ||
| ## [15.5.0] - 2022-04-19 | ||
| [15.5.0]: https://github.com/electron/electron-packager/compare/v15.4.0...v15.5.0 | ||
| ### Added | ||
| * New `universal` architecture supported when packaging for macOS to generate a universal app | ||
| * `osxUniveral` option to allow providing options to `@electron/universal` when packaging a universal app | ||
| ## [15.4.0] - 2021-09-10 | ||
@@ -9,0 +18,0 @@ |
+3
-2
| { | ||
| "name": "electron-packager", | ||
| "version": "15.4.0", | ||
| "version": "15.5.0", | ||
| "description": "Customize and package your Electron app with OS-specific bundles (.app, .exe, etc.) via JS or CLI", | ||
@@ -30,2 +30,3 @@ "main": "src/index.js", | ||
| "@electron/get": "^1.6.0", | ||
| "@electron/universal": "^1.2.1", | ||
| "asar": "^3.1.0", | ||
@@ -63,3 +64,3 @@ "cross-spawn-windows-exe": "^1.2.0", | ||
| "pkg-up": "^3.0.1", | ||
| "sinon": "^11.0.0", | ||
| "sinon": "^13.0.1", | ||
| "tsd": "^0.14.0", | ||
@@ -66,0 +67,0 @@ "typedoc": "^0.19.0", |
+2
-2
@@ -8,3 +8,3 @@ # Electron Packager | ||
| [](https://npm.im/electron-packager) | ||
| [](https://discord.gg/electron) | ||
| [](https://discord.com/invite/APGC3k5yaH) | ||
@@ -49,3 +49,3 @@ [Supported Platforms](#supported-platforms) | | ||
| * Windows (also known as `win32`, for x86, x86_64, and arm64 architectures) | ||
| * macOS (also known as `darwin`) / [Mac App Store](https://electronjs.org/docs/tutorial/mac-app-store-submission-guide/) (also known as `mas`)<sup>*</sup> (for x86_64 and arm64 architectures) | ||
| * macOS (also known as `darwin`) / [Mac App Store](https://electronjs.org/docs/tutorial/mac-app-store-submission-guide/) (also known as `mas`)<sup>*</sup> (for x86_64, arm64, and universal architectures) | ||
| * Linux (for x86, x86_64, armv7l, arm64, and mips64el architectures) | ||
@@ -52,0 +52,0 @@ |
+15
-0
@@ -19,3 +19,6 @@ // Originally based on the type definitions for electron-packager 14.0 | ||
| import { SignOptions } from 'electron-osx-sign'; | ||
| import type { makeUniversalApp } from '@electron/universal'; | ||
| type MakeUniversalOpts = Parameters<typeof makeUniversalApp>[0] | ||
| type NotarizeLegacyOptions = LegacyNotarizeCredentials & TransporterOptions; | ||
@@ -133,2 +136,8 @@ | ||
| /** | ||
| * See the documentation for [`@electron/universal`](https://github.com/electron/universal) | ||
| * for details. | ||
| */ | ||
| type OsxUniversalOptions = Omit<MakeUniversalOpts, 'x64AppPath' | 'arm64AppPath' | 'outAppPath' | 'force'> | ||
| /** | ||
| * Defines URL protocol schemes to be used on macOS. | ||
@@ -450,2 +459,8 @@ */ | ||
| /** | ||
| * Used to provide custom options to the internal call to `@electron/universal` when building a macOS | ||
| * app with the target architecture of "universal". Unused otherwise, providing a value does not imply | ||
| * a universal app is built. | ||
| */ | ||
| osxUniversal?: OsxUniversalOptions; | ||
| /** | ||
| * The base directory where the finished package(s) are created. | ||
@@ -452,0 +467,0 @@ * |
+24
-10
@@ -13,2 +13,3 @@ 'use strict' | ||
| const unzip = require('./unzip') | ||
| const { packageUniversalMac } = require('./universal') | ||
@@ -77,3 +78,3 @@ function debugHostInfo () { | ||
| async createApp (comboOpts, zipPath) { | ||
| buildDir (platform, arch) { | ||
| let buildParentDir | ||
@@ -85,3 +86,7 @@ if (this.useTempDir) { | ||
| } | ||
| const buildDir = path.resolve(buildParentDir, `${comboOpts.platform}-${comboOpts.arch}-template`) | ||
| return path.resolve(buildParentDir, `${platform}-${arch}-template`) | ||
| } | ||
| async createApp (comboOpts, zipPath) { | ||
| const buildDir = this.buildDir(comboOpts.platform, comboOpts.arch) | ||
| common.info(`Packaging app for platform ${comboOpts.platform} ${comboOpts.arch} using electron v${comboOpts.electronVersion}`, this.opts.quiet) | ||
@@ -131,11 +136,4 @@ | ||
| async packageForPlatformAndArch (downloadOpts) { | ||
| async packageForPlatformAndArchWithOpts (comboOpts, downloadOpts) { | ||
| const zipPath = await this.getElectronZipPath(downloadOpts) | ||
| // Create delegated options object with specific platform and arch, for output directory naming | ||
| const comboOpts = { | ||
| ...this.opts, | ||
| arch: downloadOpts.arch, | ||
| platform: downloadOpts.platform, | ||
| electronVersion: downloadOpts.version | ||
| } | ||
@@ -157,2 +155,18 @@ if (!this.useTempDir) { | ||
| } | ||
| async packageForPlatformAndArch (downloadOpts) { | ||
| // Create delegated options object with specific platform and arch, for output directory naming | ||
| const comboOpts = { | ||
| ...this.opts, | ||
| arch: downloadOpts.arch, | ||
| platform: downloadOpts.platform, | ||
| electronVersion: downloadOpts.version | ||
| } | ||
| if (common.isPlatformMac(comboOpts.platform) && comboOpts.arch === 'universal') { | ||
| return packageUniversalMac(this.packageForPlatformAndArchWithOpts.bind(this), this.buildDir(comboOpts.platform, comboOpts.arch), comboOpts, downloadOpts, this.tempBase) | ||
| } | ||
| return this.packageForPlatformAndArchWithOpts(comboOpts, downloadOpts) | ||
| } | ||
| } | ||
@@ -159,0 +173,0 @@ |
+7
-5
@@ -7,8 +7,8 @@ 'use strict' | ||
| const officialArchs = ['ia32', 'x64', 'armv7l', 'arm64', 'mips64el'] | ||
| const officialArchs = ['ia32', 'x64', 'armv7l', 'arm64', 'mips64el', 'universal'] | ||
| const officialPlatforms = ['darwin', 'linux', 'mas', 'win32'] | ||
| const officialPlatformArchCombos = { | ||
| darwin: ['x64', 'arm64'], | ||
| darwin: ['x64', 'arm64', 'universal'], | ||
| linux: ['ia32', 'x64', 'armv7l', 'arm64', 'mips64el'], | ||
| mas: ['x64', 'arm64'], | ||
| mas: ['x64', 'arm64', 'universal'], | ||
| win32: ['ia32', 'x64', 'arm64'] | ||
@@ -19,3 +19,4 @@ } | ||
| darwin: { | ||
| arm64: '>= 11.0.0-beta.1' | ||
| arm64: '>= 11.0.0-beta.1', | ||
| universal: '>= 11.0.0-beta.1' | ||
| }, | ||
@@ -27,3 +28,4 @@ linux: { | ||
| mas: { | ||
| arm64: '>= 11.0.0-beta.1' | ||
| arm64: '>= 11.0.0-beta.1', | ||
| universal: '>= 11.0.0-beta.1' | ||
| }, | ||
@@ -30,0 +32,0 @@ win32: { |
+3
-2
@@ -25,4 +25,5 @@ Usage: electron-packager <sourcedir> <appname> [options...] | ||
| app-version release version to set for the app | ||
| arch all, or one or more of: ia32, x64, armv7l, arm64, mips64el (comma-delimited if | ||
| multiple). Defaults to the host arch | ||
| arch all, or one or more of: ia32, x64, armv7l, arm64, mips64el, universal (comma-delimited if | ||
| multiple). Defaults to the host arch. | ||
| For info on arch/platform support see https://github.com/electron/electron-packager/#supported-platforms | ||
| asar whether to package the source code within your app into an archive. You can either | ||
@@ -29,0 +30,0 @@ pass --asar by itself to use the default configuration, OR use dot notation to |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
137806
3.31%25
4.17%2199
4.02%19
5.56%+ Added
+ Added
+ Added
+ Added
+ Added