├── .circleci └── config.yml ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github ├── CODEOWNERS ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug.yml │ ├── config.yml │ └── feature_request.yml ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── add-to-project.yml │ ├── gh-pages.yml │ ├── semantic.yml │ └── stale.yml ├── .gitignore ├── .husky ├── .gitignore ├── pre-commit ├── pre-push └── pre-push.js ├── .markdownlint.json ├── .markdownlintignore ├── .npmrc ├── .nvmrc ├── .prettierignore ├── .vscode └── extensions.json ├── CHANGELOG.md ├── CNAME ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SUPPORT.md ├── ci └── fix-changelog.js ├── lerna.json ├── nx.json ├── package.json ├── packages ├── api │ ├── cli │ │ ├── .eslintrc.json │ │ ├── package.json │ │ ├── script │ │ │ ├── vscode.cmd │ │ │ └── vscode.sh │ │ ├── spec │ │ │ ├── cli.slow.spec.ts │ │ │ └── util │ │ │ │ ├── check-system.spec.ts │ │ │ │ └── resolve-working-dir.spec.ts │ │ └── src │ │ │ ├── electron-forge-import.ts │ │ │ ├── electron-forge-init.ts │ │ │ ├── electron-forge-make.ts │ │ │ ├── electron-forge-package.ts │ │ │ ├── electron-forge-publish.ts │ │ │ ├── electron-forge-start.ts │ │ │ ├── electron-forge.ts │ │ │ └── util │ │ │ ├── check-system.ts │ │ │ ├── resolve-working-dir.ts │ │ │ └── terminate.ts │ └── core │ │ ├── .eslintignore │ │ ├── README.md │ │ ├── helper │ │ ├── dynamic-import.d.ts │ │ └── dynamic-import.js │ │ ├── package.json │ │ ├── spec │ │ ├── .eslintrc │ │ ├── fast │ │ │ ├── find-template.spec.ts │ │ │ ├── init-git.spec.ts │ │ │ ├── make.spec.ts │ │ │ ├── publish.spec.ts │ │ │ ├── start.spec.ts │ │ │ └── util │ │ │ │ ├── electron-executable.spec.ts │ │ │ │ ├── forge-config.spec.ts │ │ │ │ ├── hook.spec.ts │ │ │ │ ├── import-search.spec.ts │ │ │ │ ├── install-dependencies.spec.ts │ │ │ │ ├── out-dir.spec.ts │ │ │ │ ├── parse-archs.spec.ts │ │ │ │ ├── read-package-json.spec.ts │ │ │ │ ├── resolve-dir.spec.ts │ │ │ │ └── upgrade-forge-config.spec.ts │ │ ├── fixture │ │ │ ├── app-with-custom-maker-config │ │ │ │ ├── out │ │ │ │ │ └── test-linux-x64 │ │ │ │ │ │ └── .gitkeep │ │ │ │ └── package.json │ │ │ ├── app-with-maker-disable │ │ │ │ ├── out │ │ │ │ │ └── test-linux-x64 │ │ │ │ │ │ └── .gitkeep │ │ │ │ └── package.json │ │ │ ├── app-with-scoped-name │ │ │ │ ├── out │ │ │ │ │ └── @scope-package-linux-x64 │ │ │ │ │ │ └── .gitkeep │ │ │ │ └── package.json │ │ │ ├── async_forge_config │ │ │ │ ├── forge.config.js │ │ │ │ └── package.json │ │ │ ├── bad_external_forge_config │ │ │ │ ├── bad.js │ │ │ │ └── package.json │ │ │ ├── bad_forge_config │ │ │ │ └── package.json │ │ │ ├── bogus-private-key.pvk │ │ │ ├── custom-maker.ts │ │ │ ├── custom_init │ │ │ │ ├── index.js │ │ │ │ ├── package-lock.json │ │ │ │ ├── package.json │ │ │ │ └── tmpl │ │ │ │ │ ├── _bar │ │ │ │ │ └── src │ │ │ │ │ └── foo.js │ │ │ ├── dummy_app │ │ │ │ ├── foo │ │ │ │ │ └── null │ │ │ │ └── package.json │ │ │ ├── dummy_default_cts_conf │ │ │ │ ├── forge.config.cts │ │ │ │ └── package.json │ │ │ ├── dummy_default_esm_conf │ │ │ │ ├── forge.config.js │ │ │ │ └── package.json │ │ │ ├── dummy_default_js_conf │ │ │ │ ├── forge.config.js │ │ │ │ └── package.json │ │ │ ├── dummy_default_mts_conf │ │ │ │ ├── forge.config.mts │ │ │ │ └── package.json │ │ │ ├── dummy_default_ts_conf │ │ │ │ ├── forge.config.ts │ │ │ │ └── package.json │ │ │ ├── dummy_js_conf │ │ │ │ ├── foo.js │ │ │ │ ├── forge.different.config.js │ │ │ │ └── package.json │ │ │ ├── dummy_ts_conf │ │ │ │ ├── forge.config.yml │ │ │ │ └── package.json │ │ │ ├── electron-executable │ │ │ │ ├── bad-export │ │ │ │ │ └── node_modules │ │ │ │ │ │ ├── electron-prebuilt-compile │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── package.json │ │ │ │ │ │ └── electron │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── package.json │ │ │ │ ├── electron_app │ │ │ │ │ └── node_modules │ │ │ │ │ │ └── electron │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── package.json │ │ │ │ └── prebuilt-compile │ │ │ │ │ └── node_modules │ │ │ │ │ └── electron-prebuilt-compile │ │ │ │ │ └── package.json │ │ │ ├── electron-forge-template-fixture │ │ │ │ ├── index.js │ │ │ │ └── package.json │ │ │ ├── forge-config-no-package-json-config │ │ │ │ ├── forge.config.js │ │ │ │ └── package.json │ │ │ ├── global-stub │ │ │ │ └── node_modules │ │ │ │ │ ├── @electron-forge │ │ │ │ │ └── template-global │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── package.json │ │ │ │ │ └── electron-forge-template-global-two │ │ │ │ │ ├── index.js │ │ │ │ │ └── package.json │ │ │ ├── maker-incompatible.ts │ │ │ ├── maker-name-wrong-type │ │ │ │ └── package.json │ │ │ ├── maker-sans-name │ │ │ │ └── package.json │ │ │ ├── maker-unsupported.ts │ │ │ ├── maker-wrong-platform.ts │ │ │ ├── no_forge_config │ │ │ │ └── package.json │ │ │ ├── npm-workspace │ │ │ │ ├── package-lock.json │ │ │ │ ├── package.json │ │ │ │ └── packages │ │ │ │ │ └── subpackage │ │ │ │ │ └── .gitkeep │ │ │ ├── require-search │ │ │ │ └── throw-error.js │ │ │ ├── template-nonmatching-forge-version │ │ │ │ └── index.js │ │ │ ├── template-sans-forge-version │ │ │ │ ├── index.js │ │ │ │ └── package.json │ │ │ └── yarn-workspace │ │ │ │ └── packages │ │ │ │ ├── electron-folder-in-node-modules │ │ │ │ └── .gitkeep │ │ │ │ ├── subpackage │ │ │ │ └── .gitkeep │ │ │ │ └── with-node-modules │ │ │ │ └── .gitkeep │ │ └── slow │ │ │ ├── api.slow.spec.ts │ │ │ └── install-dependencies.slow.spec.ts │ │ └── src │ │ ├── api │ │ ├── import.ts │ │ ├── index.ts │ │ ├── init-scripts │ │ │ ├── find-template.ts │ │ │ ├── init-directory.ts │ │ │ ├── init-git.ts │ │ │ ├── init-link.ts │ │ │ └── init-npm.ts │ │ ├── init.ts │ │ ├── make.ts │ │ ├── package.ts │ │ ├── publish.ts │ │ └── start.ts │ │ └── util │ │ ├── deprecate.ts │ │ ├── electron-executable.ts │ │ ├── forge-config.ts │ │ ├── hook.ts │ │ ├── import-search.ts │ │ ├── index.ts │ │ ├── install-dependencies.ts │ │ ├── is-installed.ts │ │ ├── linux-installer.ts │ │ ├── messages.ts │ │ ├── out-dir.ts │ │ ├── parse-archs.ts │ │ ├── plugin-interface.ts │ │ ├── publish-state.ts │ │ ├── read-package-json.ts │ │ ├── resolve-dir.ts │ │ └── upgrade-forge-config.ts ├── external │ └── create-electron-app │ │ ├── README.md │ │ ├── package.json │ │ └── src │ │ └── index.ts ├── maker │ ├── appx │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ │ ├── MakerAppX.spec.ts │ │ │ └── util │ │ │ │ └── author-name.spec.ts │ │ ├── src │ │ │ ├── Config.ts │ │ │ ├── MakerAppX.ts │ │ │ └── util │ │ │ │ └── author-name.ts │ │ └── typings │ │ │ └── ambient.d.ts │ ├── base │ │ ├── package.json │ │ ├── spec │ │ │ ├── config-fetcher.spec.ts │ │ │ ├── ensure-output.spec.ts │ │ │ ├── support.spec.ts │ │ │ └── version.spec.ts │ │ └── src │ │ │ └── Maker.ts │ ├── deb │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ │ └── MakerDeb.spec.ts │ │ └── src │ │ │ ├── Config.ts │ │ │ └── MakerDeb.ts │ ├── dmg │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ │ └── MakerDMG.spec.ts │ │ └── src │ │ │ ├── Config.ts │ │ │ └── MakerDMG.ts │ ├── flatpak │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ │ └── MakerFlatpak.spec.ts │ │ └── src │ │ │ ├── Config.ts │ │ │ └── MakerFlatpak.ts │ ├── pkg │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ │ └── MakerPKG.spec.ts │ │ └── src │ │ │ ├── Config.ts │ │ │ └── MakerPKG.ts │ ├── rpm │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ │ └── MakerRpm.spec.ts │ │ └── src │ │ │ ├── Config.ts │ │ │ └── MakerRpm.ts │ ├── snap │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ │ └── MakerSnap.spec.ts │ │ └── src │ │ │ ├── Config.ts │ │ │ └── MakerSnap.ts │ ├── squirrel │ │ ├── README.md │ │ ├── package.json │ │ └── src │ │ │ └── MakerSquirrel.ts │ ├── wix │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ │ └── author-name.spec.ts │ │ ├── src │ │ │ ├── Config.ts │ │ │ ├── MakerWix.ts │ │ │ └── util │ │ │ │ └── author-name.ts │ │ └── typings │ │ │ └── ambient.d.ts │ └── zip │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ ├── MakerZip.spec.ts │ │ └── fixture │ │ │ ├── fake-app │ │ │ └── index.js │ │ │ └── fake-darwin-app │ │ │ └── My Test App.app │ │ │ └── index.js │ │ └── src │ │ ├── Config.ts │ │ └── MakerZIP.ts ├── plugin │ ├── auto-unpack-natives │ │ ├── README.md │ │ ├── package.json │ │ └── src │ │ │ ├── AutoUnpackNativesPlugin.ts │ │ │ └── Config.ts │ ├── base │ │ ├── package.json │ │ └── src │ │ │ └── Plugin.ts │ ├── electronegativity │ │ ├── README.md │ │ ├── package.json │ │ └── src │ │ │ └── ElectronegativityPlugin.ts │ ├── fuses │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ │ ├── FusesPlugin.slow.spec.ts │ │ │ └── fixture │ │ │ │ └── app │ │ │ │ ├── forge.config.ts │ │ │ │ ├── package.json │ │ │ │ ├── package.json.tmpl │ │ │ │ └── src │ │ │ │ └── main.js │ │ └── src │ │ │ ├── FusesPlugin.ts │ │ │ └── util │ │ │ └── getElectronExecutablePath.ts │ ├── local-electron │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ │ └── LocalElectronPlugin.spec.ts │ │ └── src │ │ │ ├── Config.ts │ │ │ └── LocalElectronPlugin.ts │ ├── vite │ │ ├── README.md │ │ ├── forge-vite-env.d.ts │ │ ├── package.json │ │ ├── spec │ │ │ ├── ViteConfig.spec.ts │ │ │ ├── VitePlugin.spec.ts │ │ │ ├── config │ │ │ │ └── vite.base.config.spec.ts │ │ │ └── fixtures │ │ │ │ ├── .gitignore │ │ │ │ └── vite-configs │ │ │ │ ├── vite.main.config.mjs │ │ │ │ ├── vite.preload.config.mjs │ │ │ │ └── vite.renderer.config.mjs │ │ ├── src │ │ │ ├── Config.ts │ │ │ ├── ViteConfig.ts │ │ │ ├── VitePlugin.ts │ │ │ ├── config │ │ │ │ ├── vite.base.config.ts │ │ │ │ ├── vite.main.config.ts │ │ │ │ ├── vite.preload.config.ts │ │ │ │ └── vite.renderer.config.ts │ │ │ └── util │ │ │ │ └── plugins.ts │ │ └── vite-env.d.ts │ └── webpack │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ ├── AssetRelocatorPatch.spec.ts │ │ ├── WebpackConfig.spec.ts │ │ ├── WebpackPlugin.spec.ts │ │ ├── fixtures │ │ │ ├── apps │ │ │ │ └── native-modules │ │ │ │ │ ├── package-lock.json │ │ │ │ │ ├── package.json │ │ │ │ │ ├── src │ │ │ │ │ ├── index.html │ │ │ │ │ ├── index.js │ │ │ │ │ ├── preload.js │ │ │ │ │ └── renderer.js │ │ │ │ │ ├── webpack.main.config.js │ │ │ │ │ ├── webpack.renderer.config.js │ │ │ │ │ └── webpack.rules.js │ │ │ └── main_config_external │ │ │ │ ├── mainConfig.js │ │ │ │ └── mainConfig.module.js │ │ └── util │ │ │ ├── once.spec.ts │ │ │ └── processConfig.spec.ts │ │ └── src │ │ ├── Config.ts │ │ ├── WebpackConfig.ts │ │ ├── WebpackPlugin.ts │ │ └── util │ │ ├── AssetRelocatorPatch.ts │ │ ├── ElectronForgeLogging.ts │ │ ├── EntryPointPreloadPlugin.ts │ │ ├── once.ts │ │ ├── processConfig.ts │ │ └── rendererTypeUtils.ts ├── publisher │ ├── base-static │ │ ├── package.json │ │ ├── spec │ │ │ └── StaticPublisher.spec.ts │ │ └── src │ │ │ └── PublisherStatic.ts │ ├── base │ │ ├── package.json │ │ ├── spec │ │ │ └── Publisher.spec.ts │ │ └── src │ │ │ └── Publisher.ts │ ├── bitbucket │ │ ├── README.md │ │ ├── package.json │ │ └── src │ │ │ ├── Config.ts │ │ │ └── PublisherBitbucket.ts │ ├── electron-release-server │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ │ └── PublisherERS.spec.ts │ │ └── src │ │ │ ├── Config.ts │ │ │ └── PublisherERS.ts │ ├── gcs │ │ ├── package.json │ │ └── src │ │ │ ├── Config.ts │ │ │ └── PublisherGCS.ts │ ├── github │ │ ├── README.md │ │ ├── package.json │ │ ├── spec │ │ │ └── util │ │ │ │ └── github.spec.ts │ │ └── src │ │ │ ├── Config.ts │ │ │ ├── PublisherGithub.ts │ │ │ └── util │ │ │ ├── github.ts │ │ │ └── no-release-error.ts │ ├── nucleus │ │ ├── README.md │ │ ├── package.json │ │ └── src │ │ │ ├── Config.ts │ │ │ └── PublisherNucleus.ts │ ├── s3 │ │ ├── README.md │ │ ├── package.json │ │ └── src │ │ │ ├── Config.ts │ │ │ └── PublisherS3.ts │ └── snapcraft │ │ ├── README.md │ │ ├── package.json │ │ └── src │ │ ├── Config.ts │ │ └── PublisherSnapcraft.ts ├── template │ ├── base │ │ ├── package.json │ │ ├── spec │ │ │ └── determine-author.spec.ts │ │ ├── src │ │ │ ├── BaseTemplate.ts │ │ │ └── determine-author.ts │ │ └── tmpl │ │ │ ├── _gitignore │ │ │ ├── _npmrc │ │ │ ├── forge.config.js │ │ │ ├── index.css │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── package.json │ │ │ └── preload.js │ ├── vite-typescript │ │ ├── .eslintignore │ │ ├── package.json │ │ ├── spec │ │ │ └── ViteTypeScriptTemplate.slow.spec.ts │ │ ├── src │ │ │ └── ViteTypeScriptTemplate.ts │ │ └── tmpl │ │ │ ├── .eslintrc.json │ │ │ ├── forge.config.ts │ │ │ ├── forge.env.d.ts │ │ │ ├── main.ts │ │ │ ├── package.json │ │ │ ├── preload.ts │ │ │ ├── renderer.ts │ │ │ ├── tsconfig.json │ │ │ ├── vite.main.config.ts │ │ │ ├── vite.preload.config.ts │ │ │ └── vite.renderer.config.ts │ ├── vite │ │ ├── .eslintignore │ │ ├── package.json │ │ ├── spec │ │ │ └── ViteTemplate.spec.ts │ │ ├── src │ │ │ └── ViteTemplate.ts │ │ └── tmpl │ │ │ ├── forge.config.js │ │ │ ├── index.js │ │ │ ├── package.json │ │ │ ├── preload.js │ │ │ ├── renderer.js │ │ │ ├── vite.main.config.mjs │ │ │ ├── vite.preload.config.mjs │ │ │ └── vite.renderer.config.mjs │ ├── webpack-typescript │ │ ├── package.json │ │ ├── spec │ │ │ └── WebpackTypeScript.slow.spec.ts │ │ ├── src │ │ │ └── WebpackTypeScriptTemplate.ts │ │ └── tmpl │ │ │ ├── .eslintrc.json │ │ │ ├── forge.config.ts │ │ │ ├── index.ts │ │ │ ├── package.json │ │ │ ├── preload.ts │ │ │ ├── renderer.ts │ │ │ ├── tsconfig.json │ │ │ ├── webpack.main.config.ts │ │ │ ├── webpack.plugins.ts │ │ │ ├── webpack.renderer.config.ts │ │ │ └── webpack.rules.ts │ └── webpack │ │ ├── .eslintignore │ │ ├── package.json │ │ ├── spec │ │ └── WebpackTemplate.spec.ts │ │ ├── src │ │ └── WebpackTemplate.ts │ │ └── tmpl │ │ ├── forge.config.js │ │ ├── package.json │ │ ├── preload.js │ │ ├── renderer.js │ │ ├── webpack.main.config.js │ │ ├── webpack.renderer.config.js │ │ └── webpack.rules.js └── utils │ ├── core-utils │ ├── package.json │ ├── spec │ │ ├── electron-version.spec.ts │ │ ├── fixture │ │ │ ├── dummy_app │ │ │ │ ├── foo │ │ │ │ │ └── null │ │ │ │ └── package.json │ │ │ ├── non-exact │ │ │ │ └── node_modules │ │ │ │ │ └── electron │ │ │ │ │ └── package.json │ │ │ ├── npm-workspace │ │ │ │ ├── node_modules │ │ │ │ │ └── electron │ │ │ │ │ │ └── package.json │ │ │ │ ├── package-lock.json │ │ │ │ ├── package.json │ │ │ │ └── packages │ │ │ │ │ └── subpackage │ │ │ │ │ └── .gitkeep │ │ │ └── yarn-workspace │ │ │ │ ├── node_modules │ │ │ │ └── electron │ │ │ │ │ └── package.json │ │ │ │ ├── packages │ │ │ │ ├── electron-folder-in-node-modules │ │ │ │ │ ├── .gitkeep │ │ │ │ │ └── node_modules │ │ │ │ │ │ └── electron │ │ │ │ │ │ └── package.json │ │ │ │ ├── subpackage │ │ │ │ │ └── .gitkeep │ │ │ │ └── with-node-modules │ │ │ │ │ ├── .gitkeep │ │ │ │ │ └── node_modules │ │ │ │ │ ├── some-other-module-second │ │ │ │ │ └── package.json │ │ │ │ │ └── some-other-module │ │ │ │ │ └── package.json │ │ │ │ └── yarn.lock │ │ └── package-manager.spec.ts │ └── src │ │ ├── electron-version.ts │ │ ├── index.ts │ │ ├── package-manager.ts │ │ ├── rebuild.ts │ │ └── remote-rebuild.ts │ ├── test-utils │ ├── package.json │ └── src │ │ └── index.ts │ ├── tracer │ ├── package.json │ └── src │ │ └── index.ts │ ├── types │ ├── package.json │ └── src │ │ └── index.ts │ └── web-multi-logger │ ├── README.md │ ├── package.json │ ├── src │ ├── Log.ts │ ├── Logger.ts │ └── Tab.ts │ └── static │ ├── index.html │ └── main.js ├── tools ├── .eslintrc.json ├── doc-plugin │ ├── package.json │ ├── src │ │ └── index.tsx │ ├── tsconfig.json │ └── yarn.lock ├── fix-deps.ts ├── gen-ts-glue.ts ├── gen-tsconfigs.ts ├── position-docs.ts ├── silent.js ├── sync-readmes.ts ├── test-clear.ts ├── test-dist.ts ├── update-dependencies.js ├── update-node-version.ts └── utils.ts ├── tsconfig.base.json ├── tsconfig.test.json ├── typedoc.base.json ├── typedoc.json ├── typings ├── @doyensec │ └── index.d.ts ├── cross-spawn │ └── index.d.ts ├── electron-windows-store │ └── index.d.ts ├── parse-author │ └── index.d.ts └── sudo-prompt │ └── index.d.ts ├── vitest.config.mts ├── vitest.workspace.mts └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [{*.html,*.js,*.json,*.md,*.ts,*.yml,*eslintrc}] 4 | indent_style = space 5 | indent_size = 2 6 | insert_final_newline = true 7 | max_line_length = 160 8 | trim_trailing_whitespace = true 9 | 10 | [*.sh] 11 | indent_style = space 12 | indent_size = 4 13 | insert_final_newline = true 14 | trim_trailing_whitespace = true 15 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | docs/ 3 | node_modules 4 | *.d.ts 5 | packages/*/*/doc 6 | packages/*/*/index.ts 7 | packages/**/bad.js 8 | tmpl 9 | packages/api/core/helper/dynamic-import.js 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @electron/wg-ecosystem 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: malept 2 | tidelift: npm/electron-forge 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | 3 | contact_links: 4 | - name: Question 5 | url: https://discord.gg/invite/APGC3k5yaH 6 | about: 'Please ask questions about using Electron Forge in the official Electron Discord server, at the #electron-forge channel.' 7 | - name: Documentation Issues 8 | url: https://github.com/electron-forge/electron-forge-docs/issues/new 9 | about: Documentation issues / pull requests should be filed in the website repository. 10 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'github-actions' 4 | directory: '/' 5 | schedule: 6 | interval: 'monthly' 7 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | - [ ] I have read the [contribution documentation](https://github.com/electron/forge/blob/main/CONTRIBUTING.md) for this project. 7 | - [ ] I agree to follow the [code of conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project follows, as appropriate. 8 | - [ ] The changes are appropriately documented (if applicable). 9 | - [ ] The changes have sufficient test coverage (if applicable). 10 | - [ ] The testsuite passes successfully on my local machine (if applicable). 11 | 12 | **Summarize your changes:** 13 | -------------------------------------------------------------------------------- /.github/workflows/add-to-project.yml: -------------------------------------------------------------------------------- 1 | name: Add to Ecosystem WG Project 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | pull_request_target: 8 | types: 9 | - opened 10 | 11 | permissions: {} 12 | 13 | jobs: 14 | add-to-project: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Generate GitHub App token 18 | uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1 19 | id: generate-token 20 | with: 21 | creds: ${{ secrets.ECOSYSTEM_ISSUE_TRIAGE_GH_APP_CREDS }} 22 | org: electron 23 | - name: Add to Project 24 | uses: dsanders11/project-actions/add-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0 25 | with: 26 | field: Opened 27 | field-value: ${{ github.event.pull_request.created_at || github.event.issue.created_at }} 28 | project-number: 89 29 | token: ${{ steps.generate-token.outputs.token }} 30 | -------------------------------------------------------------------------------- /.github/workflows/semantic.yml: -------------------------------------------------------------------------------- 1 | name: 'Check Semantic Commit' 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - edited 8 | - synchronize 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | main: 15 | permissions: 16 | pull-requests: read # for amannn/action-semantic-pull-request to analyze PRs 17 | statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR 18 | name: Validate PR Title 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: semantic-pull-request 22 | uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # tag: v5 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | with: 26 | validateSingleCommit: false 27 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Close issues that have been blocked for two weeks 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * *' 6 | 7 | permissions: {} 8 | 9 | jobs: 10 | stale: 11 | runs-on: ubuntu-latest 12 | permissions: 13 | issues: write 14 | pull-requests: write 15 | steps: 16 | - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 17 | with: 18 | repo-token: ${{ secrets.GITHUB_TOKEN }} 19 | any-of-labels: 'blocked/needs-info,blocked/needs-repro' 20 | labels-to-remove-when-unstale: 'blocked/needs-info,blocked/needs-repro' 21 | days-before-pr-stale: 9001 # good luck to whoever leaves their PR up for 25 years 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .nyc_output 3 | *.lcov 4 | /coverage 5 | dist 6 | docs 7 | doc 8 | node_modules 9 | lerna-debug.log 10 | yarn-error.log 11 | packages/**/.npmignore 12 | packages/**/tsconfig.json 13 | !packages/template/*/tmpl/tsconfig.json 14 | packages/**/tslint.json 15 | packages/**/yarn.lock 16 | packages/*/*/index.ts 17 | packages/.old 18 | packages/utils/types/index.d.ts 19 | packages/api/cli/README.md 20 | !packages/**/base/README.md 21 | !/README.md 22 | packages/**/tsconfig.tsbuildinfo 23 | packages/**/.swc 24 | .webpack 25 | packages/api/core/spec/fixture/app-with-scoped-name/out/make 26 | packages/plugin/webpack/spec/fixtures/apps/native-modules/package-lock.json 27 | packages/plugin/fuses/spec/fixture/app 28 | .links 29 | reports 30 | packages/**/typedoc.json 31 | .eslintcache 32 | .vscode/settings.json 33 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn lint-staged 5 | -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | BRANCH=`git rev-parse --abbrev-ref HEAD` 5 | PROTECTED_BRANCH="main" 6 | 7 | if [ "$BRANCH" = $PROTECTED_BRANCH ]; then 8 | node .husky/pre-push.js < /dev/tty 9 | fi 10 | -------------------------------------------------------------------------------- /.husky/pre-push.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const question = [ 4 | { 5 | type: 'confirm', 6 | name: 'continuePush', 7 | message: '[pre-push hook] Warning: this is a protected branch. Continue?', 8 | }, 9 | ]; 10 | 11 | inquirer.prompt(question).then((answer) => { 12 | if (!answer.continuePush) process.exit(1); 13 | process.exit(0); 14 | }); 15 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@electron/lint-roller/configs/markdownlint.json" 3 | } 4 | -------------------------------------------------------------------------------- /.markdownlintignore: -------------------------------------------------------------------------------- 1 | **/node_modules/** 2 | CHANGELOG.md 3 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # Required to run pnpm in tests because `packageManager` is set to `yarn` in `package.json` 2 | package-manager-strict=false 3 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 20.17.0 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .nyc_output 2 | dist/ 3 | docs/ 4 | packages/tsconfig.json 5 | packages/*/*/dist 6 | packages/*/*/doc 7 | packages/*/*/index.d.ts 8 | packages/*/*/index.ts 9 | packages/*/*/README.md 10 | packages/*/*/tsconfig.json 11 | packages/*/*/typedoc.json 12 | packages/api/core/spec/fixture/bad_external_forge_config/bad.js 13 | packages/plugin/webpack/spec/**/.webpack 14 | .links 15 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "vitest.explorer"] 3 | } 4 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | js.electronforge.io 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Samuel Attard 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | the Software, and to permit persons to whom the Software is furnished to do so, 9 | subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /ci/fix-changelog.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | const prettier = require('prettier'); 5 | 6 | const changelogPath = path.resolve(__dirname, '..', 'CHANGELOG.md'); 7 | 8 | const changelog = fs.readFileSync(changelogPath, 'utf8'); 9 | 10 | const fixedChangelog = changelog 11 | .replace(/\(([A-Za-z0-9]{8})\)/g, (match, commitID) => `([${commitID}](https://github.com/electron/forge/commit/${commitID}))`) 12 | .replace( 13 | /# ([0-9]+\.[0-9]+\.[0-9]+(?:-[a-z]+.[0-9]+)?) /g, 14 | (match, version) => `# [${version}](https://github.com/electron/forge/releases/tag/v${version}) ` 15 | ); 16 | 17 | fs.writeFileSync( 18 | changelogPath, 19 | prettier.format(fixedChangelog, { 20 | parser: 'markdown', 21 | }) 22 | ); 23 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "node_modules/lerna/schemas/lerna-schema.json", 3 | "version": "7.8.1", 4 | "npmClient": "yarn" 5 | } 6 | -------------------------------------------------------------------------------- /nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "tasksRunnerOptions": { 3 | "default": { 4 | "runner": "nx/tasks-runners/default", 5 | "options": { 6 | "cacheableOperations": ["coverage:base", "test", "test:base", "test:fast", "test:slow"] 7 | } 8 | } 9 | }, 10 | "targetDefaults": { 11 | "coverage:base": { 12 | "dependsOn": ["^coverage:base"] 13 | }, 14 | "test": { 15 | "dependsOn": ["^test"] 16 | }, 17 | "test:base": { 18 | "dependsOn": ["^test:base"] 19 | }, 20 | "test:fast": { 21 | "dependsOn": ["^test:fast"] 22 | }, 23 | "test:slow": { 24 | "dependsOn": ["^test:slow"] 25 | } 26 | }, 27 | "$schema": "./node_modules/nx/schemas/nx-schema.json", 28 | "namedInputs": { 29 | "default": ["{projectRoot}/**/*", "sharedGlobals"], 30 | "sharedGlobals": [], 31 | "production": ["default"] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/api/cli/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-console": "off" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/api/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/cli", 3 | "version": "7.8.1", 4 | "description": "A complete tool for building modern Electron applications", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "bin": { 9 | "electron-forge": "dist/electron-forge.js", 10 | "electron-forge-vscode-nix": "script/vscode.sh", 11 | "electron-forge-vscode-win": "script/vscode.cmd" 12 | }, 13 | "devDependencies": { 14 | "@malept/cross-spawn-promise": "^2.0.0", 15 | "vitest": "^3.1.3" 16 | }, 17 | "dependencies": { 18 | "@electron-forge/core": "7.8.1", 19 | "@electron-forge/core-utils": "7.8.1", 20 | "@electron-forge/shared-types": "7.8.1", 21 | "@electron/get": "^3.0.0", 22 | "chalk": "^4.0.0", 23 | "commander": "^11.1.0", 24 | "debug": "^4.3.1", 25 | "fs-extra": "^10.0.0", 26 | "listr2": "^7.0.2", 27 | "log-symbols": "^4.0.0", 28 | "semver": "^7.2.1" 29 | }, 30 | "engines": { 31 | "node": ">= 16.4.0" 32 | }, 33 | "funding": [ 34 | { 35 | "type": "individual", 36 | "url": "https://github.com/sponsors/malept" 37 | }, 38 | { 39 | "type": "tidelift", 40 | "url": "https://tidelift.com/subscription/pkg/npm-.electron-forge-cli?utm_medium=referral&utm_source=npm_fund" 41 | } 42 | ], 43 | "publishConfig": { 44 | "access": "public" 45 | }, 46 | "files": [ 47 | "dist", 48 | "src", 49 | "script" 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /packages/api/cli/script/vscode.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | SETLOCAL 4 | SET FORGE_ARGS=%* 5 | 6 | SET FORGE_ARGS=%FORGE_ARGS: =~ ~% 7 | node "%~dp0/../../../@electron-forge/cli/dist/electron-forge-start.js" --vscode -- ~%FORGE_ARGS%~ 8 | 9 | ENDLOCAL 10 | -------------------------------------------------------------------------------- /packages/api/cli/script/vscode.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | 4 | ARGS=$@ 5 | ARGS=${ARGS// /\~ \~} 6 | 7 | node $DIR/../../../@electron-forge/cli/dist/electron-forge-start --vscode -- \~$ARGS\~ 8 | -------------------------------------------------------------------------------- /packages/api/cli/spec/cli.slow.spec.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { spawn } from '@malept/cross-spawn-promise'; 4 | import { describe, expect, it } from 'vitest'; 5 | 6 | function runForgeCLI(...extraArgs: string[]): Promise { 7 | const args = ['ts-node', path.resolve(__dirname, '../src/electron-forge.ts'), ...extraArgs]; 8 | return spawn('npx', args); 9 | } 10 | 11 | describe('cli', () => { 12 | it('should not fail on known subcommands', async () => { 13 | await expect(runForgeCLI('help')).resolves.toMatch(/Usage:/); 14 | }); 15 | 16 | it('should fail on unknown subcommands', async () => { 17 | await expect(runForgeCLI('nonexistent')).rejects.toThrow(Error); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/api/cli/src/electron-forge-import.ts: -------------------------------------------------------------------------------- 1 | import { api } from '@electron-forge/core'; 2 | import { program } from 'commander'; 3 | 4 | import './util/terminate'; 5 | import packageJSON from '../package.json'; 6 | 7 | import { resolveWorkingDir } from './util/resolve-working-dir'; 8 | 9 | program 10 | .version(packageJSON.version, '-V, --version', 'Output the current version.') 11 | .helpOption('-h, --help', 'Output usage information.') 12 | .argument('[dir]', 'Directory of the project to import. (default: current directory)') 13 | .option('--skip-git', 'Skip initializing a git repository in the imported project.', false) 14 | .action(async (dir: string) => { 15 | const workingDir = resolveWorkingDir(dir, false); 16 | 17 | const options = program.opts(); 18 | 19 | await api.import({ 20 | dir: workingDir, 21 | interactive: true, 22 | skipGit: !!options.skipGit, 23 | }); 24 | }) 25 | .parse(process.argv); 26 | -------------------------------------------------------------------------------- /packages/api/cli/src/electron-forge-init.ts: -------------------------------------------------------------------------------- 1 | import { api, InitOptions } from '@electron-forge/core'; 2 | import { program } from 'commander'; 3 | 4 | import './util/terminate'; 5 | import packageJSON from '../package.json'; 6 | 7 | import { resolveWorkingDir } from './util/resolve-working-dir'; 8 | 9 | program 10 | .version(packageJSON.version, '-V, --version', 'Output the current version.') 11 | .helpOption('-h, --help', 'Output usage information.') 12 | .argument('[dir]', 'Directory to initialize the project in. (default: current directory)') 13 | .option('-t, --template [name]', 'Name of the Forge template to use.', 'base') 14 | .option('-c, --copy-ci-files', 'Whether to copy the templated CI files.', false) 15 | .option('-f, --force', 'Whether to overwrite an existing directory.', false) 16 | .option('--skip-git', 'Skip initializing a git repository in the initialized project.', false) 17 | .action(async (dir) => { 18 | const workingDir = resolveWorkingDir(dir, false); 19 | 20 | const options = program.opts(); 21 | 22 | const initOpts: InitOptions = { 23 | dir: workingDir, 24 | interactive: true, 25 | copyCIFiles: !!options.copyCiFiles, 26 | force: !!options.force, 27 | skipGit: !!options.skipGit, 28 | }; 29 | if (options.template) initOpts.template = options.template; 30 | 31 | await api.init(initOpts); 32 | }) 33 | .parse(process.argv); 34 | -------------------------------------------------------------------------------- /packages/api/cli/src/electron-forge-package.ts: -------------------------------------------------------------------------------- 1 | import { initializeProxy } from '@electron/get'; 2 | import { api, PackageOptions } from '@electron-forge/core'; 3 | import { program } from 'commander'; 4 | 5 | import './util/terminate'; 6 | import packageJSON from '../package.json'; 7 | 8 | import { resolveWorkingDir } from './util/resolve-working-dir'; 9 | 10 | program 11 | .version(packageJSON.version, '-V, --version', 'Output the current version') 12 | .helpOption('-h, --help', 'Output usage information') 13 | .argument('[dir]', 'Directory to run the command in. (default: current directory)') 14 | .option('-a, --arch [arch]', 'Target build architecture') 15 | .option('-p, --platform [platform]', 'Target build platform') 16 | .action(async (dir) => { 17 | const workingDir = resolveWorkingDir(dir); 18 | 19 | const options = program.opts(); 20 | 21 | initializeProxy(); 22 | 23 | const packageOpts: PackageOptions = { 24 | dir: workingDir, 25 | interactive: true, 26 | }; 27 | if (options.arch) packageOpts.arch = options.arch; 28 | if (options.platform) packageOpts.platform = options.platform; 29 | 30 | await api.package(packageOpts); 31 | }) 32 | .parse(process.argv); 33 | -------------------------------------------------------------------------------- /packages/api/cli/src/util/resolve-working-dir.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import fs from 'fs-extra'; 4 | 5 | /** 6 | * Resolves the directory in which to use a CLI command. 7 | * @param dir - The directory specified by the user (can be relative or absolute) 8 | * @param checkExisting - Checks if the directory exists. If true and directory is non-existent, it will fall back to the current working directory 9 | * @returns 10 | */ 11 | export function resolveWorkingDir(dir: string, checkExisting = true): string { 12 | if (!dir) { 13 | return process.cwd(); 14 | } 15 | 16 | const resolved = path.isAbsolute(dir) ? dir : path.resolve(process.cwd(), dir); 17 | 18 | if (checkExisting && !fs.existsSync(resolved)) { 19 | return process.cwd(); 20 | } else { 21 | return resolved; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/api/cli/src/util/terminate.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | 3 | function redConsoleError(msg: string) { 4 | console.error(chalk.red(msg)); 5 | } 6 | 7 | process.on('unhandledRejection', (reason: string, promise: Promise) => { 8 | redConsoleError('\nAn unhandled rejection has occurred inside Forge:'); 9 | redConsoleError(reason.toString().trim()); 10 | promise.catch((err: Error) => { 11 | if ('stack' in err) { 12 | const usefulStack = err.stack; 13 | if (usefulStack?.startsWith(reason.toString().trim())) { 14 | redConsoleError(usefulStack.substring(reason.toString().trim().length + 1).trim()); 15 | } 16 | } 17 | process.exit(1); 18 | }); 19 | }); 20 | 21 | process.on('uncaughtException', (err) => { 22 | if (err && err.message && err.stack) { 23 | redConsoleError('\nAn unhandled exception has occurred inside Forge:'); 24 | redConsoleError(err.message); 25 | redConsoleError(err.stack); 26 | } else { 27 | redConsoleError('\nElectron Forge was terminated:'); 28 | redConsoleError(typeof err === 'string' ? err : JSON.stringify(err)); 29 | } 30 | process.exit(1); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/api/core/.eslintignore: -------------------------------------------------------------------------------- 1 | tmpl 2 | -------------------------------------------------------------------------------- /packages/api/core/README.md: -------------------------------------------------------------------------------- 1 | # Electron Forge Core 2 | 3 | This module contains the core logic of Electron Forge and exposes the base 4 | API as a number of simple JS functions. 5 | 6 | ## Basic Usage 7 | 8 | ```javascript 9 | import { api } from '@electron-forge/core'; 10 | 11 | // Package the current directory as an Electron app 12 | api.package(__dirname); 13 | ``` 14 | 15 | The named export `api` has it's methods documented over at [ForgeAPI](https://js.electronforge.io/classes/_electron_forge_core.ForgeAPI.html). 16 | All the methods are async and expose the core forge methods, please note that all 17 | user-side configuration is still done through your forge config file or the "config.forge" 18 | section of your package.json. This API simply let's you call the methods in 19 | node land without using the CLI. 20 | 21 | ## Error Handling 22 | 23 | As all methods return a promise you should handle all rejections, you should note 24 | that rejections will **not** always be errors, in fact we commonly reject our 25 | promises with just strings so do not assume that properties such as `stack` or 26 | `message` will exist on thrown errors. 27 | -------------------------------------------------------------------------------- /packages/api/core/helper/dynamic-import.d.ts: -------------------------------------------------------------------------------- 1 | export declare function dynamicImport(path: string): Promise; 2 | /** Like {@link dynamicImport()}, except it tries out {@link require()} first. */ 3 | export declare function dynamicImportMaybe(path: string): Promise; 4 | -------------------------------------------------------------------------------- /packages/api/core/helper/dynamic-import.js: -------------------------------------------------------------------------------- 1 | const url = require('url'); 2 | const fs = require('fs'); 3 | 4 | exports.dynamicImport = async function dynamicImport(path) { 5 | try { 6 | return await import(fs.existsSync(path) ? url.pathToFileURL(path) : path); 7 | } catch (error) { 8 | return Promise.reject(error); 9 | } 10 | }; 11 | 12 | exports.dynamicImportMaybe = async function dynamicImportMaybe(path) { 13 | try { 14 | return require(path); 15 | } catch (e1) { 16 | try { 17 | return await exports.dynamicImport(path); 18 | } catch (e2) { 19 | e1.message = '\n1. ' + e1.message + '\n2. ' + e2.message; 20 | throw e1; 21 | } 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /packages/api/core/spec/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "class-methods-use-this": 0, 4 | "import/no-extraneous-dependencies": 0 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/api/core/spec/fast/util/electron-executable.spec.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { describe, expect, it } from 'vitest'; 4 | 5 | import locateElectronExecutable from '../../../src/util/electron-executable'; 6 | 7 | const fixtureDir = path.resolve(__dirname, '..', '..', 'fixture', 'electron-executable'); 8 | 9 | describe('locateElectronExecutable', () => { 10 | it('returns the correct path to electron', async () => { 11 | const appFixture = path.join(fixtureDir, 'electron_app'); 12 | const packageJSON = { 13 | devDependencies: { electron: '^100.0.0' }, 14 | }; 15 | 16 | await expect(locateElectronExecutable(appFixture, packageJSON)).resolves.toEqual('execPath'); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/api/core/spec/fast/util/import-search.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | 3 | import findConfig from '../../../src/util/forge-config'; 4 | import importSearch from '../../../src/util/import-search'; 5 | 6 | describe('import-search', () => { 7 | it('should resolve null if no file exists', async () => { 8 | const resolved = await importSearch(__dirname, ['../../../src/util/wizard-secrets']); 9 | expect(resolved).toEqual(null); 10 | }); 11 | 12 | it('should resolve a file if it exists', async () => { 13 | const resolved = await importSearch(__dirname, ['../../../src/util/forge-config']); 14 | expect(resolved).toEqual(findConfig); 15 | }); 16 | 17 | it('should throw if file exists but fails to load', async () => { 18 | await expect(importSearch(__dirname, ['../../fixture/require-search/throw-error'])).rejects.toThrowError('test'); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/api/core/spec/fast/util/parse-archs.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | 3 | import parseArchs from '../../../src/util/parse-archs'; 4 | 5 | describe('parse-archs', () => { 6 | it('should make an Array out of one arch', () => { 7 | expect(parseArchs('linux', 'x64', '1.7.0')).toEqual(['x64']); 8 | }); 9 | 10 | it('should transform comma-separated values into an Array', () => { 11 | expect(parseArchs('linux', 'ia32,x64', '1.7.0')).toEqual(['ia32', 'x64']); 12 | }); 13 | 14 | it('should use the official Electron arch list when arch is "all"', () => { 15 | expect(parseArchs('win32', 'all', '1.7.0')).toEqual(['ia32', 'x64']); 16 | expect(parseArchs('win32', 'all', '33.0.0')).toEqual(['ia32', 'x64', 'arm64']); 17 | }); 18 | 19 | it('should default to [x64] when the platform is unknown', () => { 20 | expect(parseArchs('nonexistent', 'all', '1.7.0')).toEqual(['x64']); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/api/core/spec/fast/util/read-package-json.spec.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { ResolvedForgeConfig } from '@electron-forge/shared-types'; 4 | import { describe, expect, it } from 'vitest'; 5 | 6 | import packageJSON from '../../../package.json'; 7 | import { readMutatedPackageJson, readRawPackageJson } from '../../../src/util/read-package-json'; 8 | 9 | describe('readRawPackageJson', () => { 10 | it('should find a package.json file from the given directory', async () => { 11 | const raw = await readRawPackageJson(path.resolve(__dirname, '../../../')); 12 | // eslint-disable-next-line @typescript-eslint/no-require-imports 13 | expect(raw).toEqual(packageJSON); 14 | }); 15 | }); 16 | 17 | describe('readMutatedPackageJson', () => { 18 | it('should find a package.json file from the given directory', async () => { 19 | expect( 20 | await readMutatedPackageJson(path.resolve(__dirname, '../../../'), { 21 | pluginInterface: { 22 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 23 | triggerMutatingHook: (_hookName: string, pj: any) => Promise.resolve(pj), 24 | }, 25 | } as unknown as ResolvedForgeConfig) 26 | ).toEqual(packageJSON); 27 | }); 28 | 29 | it('should allow mutations from hooks', async () => { 30 | expect( 31 | await readMutatedPackageJson(path.resolve(__dirname, '../../../'), { 32 | pluginInterface: { 33 | triggerMutatingHook: () => Promise.resolve('test_mutation'), 34 | }, 35 | } as unknown as ResolvedForgeConfig) 36 | ).toEqual('test_mutation'); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/app-with-custom-maker-config/out/test-linux-x64/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/app-with-custom-maker-config/out/test-linux-x64/.gitkeep -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/app-with-custom-maker-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "config": { 4 | "forge": { 5 | "makers": [ 6 | { 7 | "name": "../custom-maker", 8 | "config": { 9 | "artifactPath": "from config" 10 | } 11 | }, 12 | { 13 | "name": "@electron-forge/non-existent-forge-maker" 14 | } 15 | ] 16 | } 17 | }, 18 | "devDependencies": { 19 | "electron": "^1000.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/app-with-maker-disable/out/test-linux-x64/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/app-with-maker-disable/out/test-linux-x64/.gitkeep -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/app-with-maker-disable/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "config": { 4 | "forge": { 5 | "makers": [ 6 | { 7 | "name": "@electron-forge/maker-zip", 8 | "enabled": false, 9 | "platforms": [ 10 | "linux" 11 | ] 12 | } 13 | ] 14 | } 15 | }, 16 | "devDependencies": { 17 | "electron": "^1000.0.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/app-with-scoped-name/out/@scope-package-linux-x64/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/app-with-scoped-name/out/@scope-package-linux-x64/.gitkeep -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/app-with-scoped-name/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@scope/package", 3 | "productName": "", 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "src/index.js", 7 | "scripts": { 8 | "start": "electron-forge start" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "MIT", 13 | "config": { 14 | "forge": { 15 | "makers": [ 16 | { 17 | "name": "@electron-forge/maker-zip", 18 | "platforms": [ 19 | "linux" 20 | ] 21 | } 22 | ] 23 | } 24 | }, 25 | "devDependencies": { 26 | "electron": "1000.100.10" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/async_forge_config/forge.config.js: -------------------------------------------------------------------------------- 1 | module.exports = async function () { 2 | return { 3 | packagerConfig: { foo: {} }, 4 | rebuildConfig: {}, 5 | makers: [ 6 | { 7 | name: '@electron-forge/maker-zip', 8 | platforms: ['darwin'], 9 | }, 10 | ], 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/async_forge_config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "async-test", 3 | "devDependencies": { 4 | "electron": "^1000.0.0", 5 | "@electron-forge/cli": "6.0.0", 6 | "@electron-forge/core": "6.0.0" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/bad_external_forge_config/bad.js: -------------------------------------------------------------------------------- 1 | } 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/bad_external_forge_config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "forge": "bad.js" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/bad_forge_config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "forge": 1 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/bogus-private-key.pvk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/bogus-private-key.pvk -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/custom-maker.ts: -------------------------------------------------------------------------------- 1 | import { MakerBase } from '@electron-forge/maker-base'; 2 | import { ForgePlatform } from '@electron-forge/shared-types'; 3 | 4 | interface Config { 5 | artifactPath: string; 6 | } 7 | 8 | export default class Maker extends MakerBase { 9 | name = 'custom-maker'; 10 | 11 | defaultPlatforms = ['linux'] as ForgePlatform[]; 12 | 13 | isSupportedOnCurrentPlatform(): boolean { 14 | return true; 15 | } 16 | 17 | async make(): Promise { 18 | return Promise.resolve([this.config.artifactPath || 'default']); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/custom_init/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | const baseTemplate = require('@electron-forge/template-base').default; 4 | const fs = require('fs-extra'); 5 | 6 | module.exports = { 7 | requiredForgeVersion: '>= 6.0.0-beta.1', 8 | dependencies: [...baseTemplate.dependencies, 'debug'], 9 | devDependencies: [...baseTemplate.devDependencies, 'lodash'], 10 | initializeTemplate: async (directory) => { 11 | const tasks = await baseTemplate.initializeTemplate(directory, {}); 12 | return [ 13 | ...tasks, 14 | { 15 | title: 'Adding custom template files', 16 | task: async () => { 17 | await fs.copy(path.resolve(__dirname, 'tmpl', '_bar'), path.resolve(directory, '.bar')); 18 | await fs.copy(path.resolve(__dirname, 'tmpl', 'src'), path.resolve(directory, 'src')); 19 | }, 20 | }, 21 | ]; 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/custom_init/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-forge-template-dummy", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/custom_init/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-forge-template-dummy", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "electron-forge start" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "MIT" 12 | } 13 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/custom_init/tmpl/_bar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/custom_init/tmpl/_bar -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/custom_init/tmpl/src/foo.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/custom_init/tmpl/src/foo.js -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_app/foo/null: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/dummy_app/foo/null -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "productName": "", 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "src/index.js", 7 | "scripts": { 8 | "start": "electron-forge start" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "MIT", 13 | "config": { 14 | "forge": { 15 | "packagerConfig": { 16 | "baz": {} 17 | }, 18 | "s3": {} 19 | } 20 | }, 21 | "devDependencies": { 22 | "electron": "1000.100.10" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_default_cts_conf/forge.config.cts: -------------------------------------------------------------------------------- 1 | import type { ForgeConfig } from '@electron-forge/shared-types'; 2 | 3 | const config: ForgeConfig = { 4 | buildIdentifier: 'typescript-commonjs', 5 | }; 6 | 7 | export default config; 8 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_default_cts_conf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "productName": "", 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "src/index.js", 7 | "type": "commonjs", 8 | "scripts": { 9 | "start": "electron-forge start" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "@electron-forge/shared-types": "*", 16 | "electron": "99.99.99" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_default_esm_conf/forge.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | buildIdentifier: 'esm', 3 | defaultResolved: true, 4 | }; 5 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_default_esm_conf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "productName": "", 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "src/index.js", 7 | "type": "module", 8 | "scripts": { 9 | "start": "electron-forge start" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "electron-prebuilt": "9.9.9" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_default_js_conf/forge.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | buildIdentifier: 'default', 3 | }; 4 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_default_js_conf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "productName": "", 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "src/index.js", 7 | "scripts": { 8 | "start": "electron-forge start" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "electron": "99.99.99" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_default_mts_conf/forge.config.mts: -------------------------------------------------------------------------------- 1 | import type { ForgeConfig } from '@electron-forge/shared-types'; 2 | 3 | const config: ForgeConfig = { 4 | buildIdentifier: 'typescript-esm', 5 | }; 6 | 7 | export default config; 8 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_default_mts_conf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "productName": "", 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "src/index.js", 7 | "type": "module", 8 | "scripts": { 9 | "start": "electron-forge start" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "@electron-forge/shared-types": "*", 16 | "electron": "99.99.99" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_default_ts_conf/forge.config.ts: -------------------------------------------------------------------------------- 1 | import type { ForgeConfig } from '@electron-forge/shared-types'; 2 | 3 | const config: ForgeConfig = { 4 | buildIdentifier: 'typescript', 5 | }; 6 | 7 | export default config; 8 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_default_ts_conf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "productName": "", 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "src/index.js", 7 | "scripts": { 8 | "start": "electron-forge start" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "@electron-forge/shared-types": "*", 15 | "electron": "99.99.99" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_js_conf/foo.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bar: { 3 | baz: 'quux', 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_js_conf/forge.different.config.js: -------------------------------------------------------------------------------- 1 | const { 2 | utils: { fromBuildIdentifier }, 3 | } = require('@electron-forge/core'); 4 | 5 | module.exports = { 6 | buildIdentifier: 'beta', 7 | makers: [], 8 | publishers: [], 9 | hooks: { 10 | preStart: () => { 11 | return 'running preStart hook'; 12 | }, 13 | }, 14 | packagerConfig: { foo: 'bar', baz: {} }, 15 | s3: {}, 16 | electronReleaseServer: {}, 17 | topLevelProp: fromBuildIdentifier({ beta: 'foo' }), 18 | topLevelUndef: fromBuildIdentifier({ stable: 'heya' }), 19 | regexp: /foo/, 20 | sub: { 21 | prop: { 22 | inArray: [fromBuildIdentifier({ beta: 'arr' }), 'natural', 'array'], 23 | deep: { 24 | prop: fromBuildIdentifier({ beta: 'bar' }), 25 | }, 26 | }, 27 | }, 28 | }; 29 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_js_conf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "productName": "", 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "src/index.js", 7 | "scripts": { 8 | "start": "electron-forge start" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "MIT", 13 | "config": { 14 | "forge": "./forge.different.config.js" 15 | }, 16 | "devDependencies": { 17 | "electron": "99.99.99" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_ts_conf/forge.config.yml: -------------------------------------------------------------------------------- 1 | buildIdentifier: 'yml' 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/dummy_ts_conf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "productName": "", 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "src/index.js", 7 | "scripts": { 8 | "start": "electron-forge start" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "MIT", 13 | "config": { 14 | "forge": "./forge.config.yml" 15 | }, 16 | "devDependencies": { 17 | "@electron-forge/shared-types": "*", 18 | "electron": "99.99.99" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/electron-executable/bad-export/node_modules/electron-prebuilt-compile/index.js: -------------------------------------------------------------------------------- 1 | module.exports = undefined 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/electron-executable/bad-export/node_modules/electron-prebuilt-compile/package.json: -------------------------------------------------------------------------------- 1 | {"main":"index.js"} 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/electron-executable/bad-export/node_modules/electron/index.js: -------------------------------------------------------------------------------- 1 | module.exports = "execPath" 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/electron-executable/bad-export/node_modules/electron/package.json: -------------------------------------------------------------------------------- 1 | {"main":"index.js"} 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/electron-executable/electron_app/node_modules/electron/index.js: -------------------------------------------------------------------------------- 1 | module.exports = "execPath" 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/electron-executable/electron_app/node_modules/electron/package.json: -------------------------------------------------------------------------------- 1 | {"main":"index.js"} 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/electron-executable/prebuilt-compile/node_modules/electron-prebuilt-compile/package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/electron-forge-template-fixture/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { name: 'electron-forge-template-fixture' }; 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/electron-forge-template-fixture/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "index.js", 3 | "type": "commonjs", 4 | "version": "13.3.7" 5 | } 6 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/forge-config-no-package-json-config/forge.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | packagerConfig: {}, 3 | rebuildConfig: {}, 4 | makers: [ 5 | { 6 | name: '@electron-forge/maker-squirrel', 7 | config: {}, 8 | }, 9 | { 10 | name: '@electron-forge/maker-zip', 11 | platforms: ['darwin'], 12 | }, 13 | { 14 | name: '@electron-forge/maker-deb', 15 | config: {}, 16 | }, 17 | { 18 | name: '@electron-forge/maker-rpm', 19 | config: {}, 20 | }, 21 | ], 22 | }; 23 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/forge-config-no-package-json-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "devDependencies": { 4 | "electron": "^1000.0.0", 5 | "@electron-forge/cli": "6.0.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/global-stub/node_modules/@electron-forge/template-global/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { name: 'electron-forge-template-fixture-global' }; 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/global-stub/node_modules/@electron-forge/template-global/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "index.js", 3 | "type":"commonjs", 4 | "version": "13.3.7" 5 | } 6 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/global-stub/node_modules/electron-forge-template-global-two/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { name: 'electron-forge-template-fixture-global' }; 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/global-stub/node_modules/electron-forge-template-global-two/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "index.js", 3 | "type":"commonjs", 4 | "version": "13.3.7" 5 | } 6 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/maker-incompatible.ts: -------------------------------------------------------------------------------- 1 | export default class Maker { 2 | // Just so the maker isn't excluded 3 | platforms = [process.platform]; 4 | 5 | async lol(): Promise { 6 | // lol 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/maker-name-wrong-type/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "forge": { 4 | "makers": [ 5 | { 6 | "name": 1 7 | } 8 | ] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/maker-sans-name/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "forge": { 4 | "makers": [ 5 | {} 6 | ] 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/maker-unsupported.ts: -------------------------------------------------------------------------------- 1 | export default class Maker { 2 | // Just so the maker isn't excluded 3 | platforms = [process.platform]; 4 | 5 | isSupportedOnCurrentPlatform(): boolean { 6 | return false; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/maker-wrong-platform.ts: -------------------------------------------------------------------------------- 1 | export default class Maker { 2 | platforms = ['win32']; 3 | } 4 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/no_forge_config/package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/npm-workspace/package-lock.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/npm-workspace/package-lock.json -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/npm-workspace/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "workspaces": [ 3 | "packages/subpackage" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/npm-workspace/packages/subpackage/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/npm-workspace/packages/subpackage/.gitkeep -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/require-search/throw-error.js: -------------------------------------------------------------------------------- 1 | throw new Error('test'); 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/template-nonmatching-forge-version/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { requiredForgeVersion: '6.0.0-beta.0' }; 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/template-sans-forge-version/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/template-sans-forge-version/index.js -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/template-sans-forge-version/package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/yarn-workspace/packages/electron-folder-in-node-modules/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/yarn-workspace/packages/electron-folder-in-node-modules/.gitkeep -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/yarn-workspace/packages/subpackage/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/yarn-workspace/packages/subpackage/.gitkeep -------------------------------------------------------------------------------- /packages/api/core/spec/fixture/yarn-workspace/packages/with-node-modules/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/api/core/spec/fixture/yarn-workspace/packages/with-node-modules/.gitkeep -------------------------------------------------------------------------------- /packages/api/core/spec/slow/install-dependencies.slow.spec.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs/promises'; 2 | import os from 'node:os'; 3 | import path from 'node:path'; 4 | 5 | import { PACKAGE_MANAGERS } from '@electron-forge/core-utils'; 6 | import { afterAll, beforeAll, describe, expect, it } from 'vitest'; 7 | 8 | import installDeps from '../../src/util/install-dependencies'; 9 | 10 | describe.runIf(!(process.platform === 'linux' && process.env.CI))('install-dependencies', () => { 11 | let installDir: string; 12 | 13 | beforeAll(async () => { 14 | const tmp = os.tmpdir(); 15 | const tmpdir = path.join(tmp, 'electron-forge-test-'); 16 | installDir = await fs.mkdtemp(tmpdir); 17 | }); 18 | 19 | it('should install the latest minor version when the dependency has a caret', async () => { 20 | await installDeps(PACKAGE_MANAGERS['npm'], installDir, ['debug@^2.0.0']); 21 | 22 | const packageJSON = await import(path.resolve(installDir, 'node_modules', 'debug', 'package.json')); 23 | expect(packageJSON.version).not.toEqual('2.0.0'); 24 | }); 25 | 26 | afterAll(async () => fs.rm(installDir, { recursive: true, force: true })); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/api/core/src/api/init-scripts/init-directory.ts: -------------------------------------------------------------------------------- 1 | import { ForgeListrTask } from '@electron-forge/shared-types'; 2 | import debug from 'debug'; 3 | import fs from 'fs-extra'; 4 | import logSymbols from 'log-symbols'; 5 | 6 | const d = debug('electron-forge:init:directory'); 7 | 8 | export const initDirectory = async (dir: string, task: ForgeListrTask, force = false): Promise => { 9 | d('creating directory:', dir); 10 | await fs.mkdirs(dir); 11 | 12 | const files = await fs.readdir(dir); 13 | if (files.length !== 0) { 14 | d(`found ${files.length} files in the directory. warning the user`); 15 | 16 | if (force) { 17 | task.output = `${logSymbols.warning} The specified path "${dir}" is not empty. "force" was set to true, so proceeding to initialize. Files may be overwritten`; 18 | } else { 19 | throw new Error(`The specified path: "${dir}" is not empty. Please ensure it is empty before initializing a new project`); 20 | } 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /packages/api/core/src/api/init-scripts/init-git.ts: -------------------------------------------------------------------------------- 1 | import { exec } from 'node:child_process'; 2 | 3 | import debug from 'debug'; 4 | 5 | const d = debug('electron-forge:init:git'); 6 | 7 | export const initGit = async (dir: string): Promise => { 8 | await new Promise((resolve, reject) => { 9 | exec( 10 | 'git rev-parse --show-toplevel', 11 | { 12 | cwd: dir, 13 | }, 14 | (err) => { 15 | if (err) { 16 | // not run within a Git repository 17 | d('executing "git init" in directory:', dir); 18 | exec('git init', { cwd: dir }, (initErr) => (initErr ? reject(initErr) : resolve())); 19 | } else { 20 | d('.git directory already exists, skipping git initialization'); 21 | resolve(); 22 | } 23 | } 24 | ); 25 | }); 26 | }; 27 | -------------------------------------------------------------------------------- /packages/api/core/src/util/deprecate.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import logSymbols from 'log-symbols'; 3 | 4 | type Deprecation = { 5 | replaceWith: (replacement: string) => void; 6 | }; 7 | 8 | export default (what: string): Deprecation => ({ 9 | replaceWith: (replacement: string): void => { 10 | console.warn(logSymbols.warning, chalk.yellow(`WARNING: ${what} is deprecated, please use ${replacement} instead`)); 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /packages/api/core/src/util/electron-executable.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { getElectronModulePath } from '@electron-forge/core-utils'; 4 | import logSymbols from 'log-symbols'; 5 | 6 | type PackageJSON = Record; 7 | 8 | export default async function locateElectronExecutable(dir: string, packageJSON: PackageJSON): Promise { 9 | const electronModulePath: string | undefined = await getElectronModulePath(dir, packageJSON); 10 | 11 | // eslint-disable-next-line @typescript-eslint/no-require-imports 12 | let electronExecPath = require(electronModulePath || path.resolve(dir, 'node_modules/electron')); 13 | 14 | if (typeof electronExecPath !== 'string') { 15 | console.warn(logSymbols.warning, 'Returned Electron executable path is not a string, defaulting to a hardcoded location. Value:', electronExecPath); 16 | // eslint-disable-next-line @typescript-eslint/no-require-imports 17 | electronExecPath = require(path.resolve(dir, 'node_modules/electron')); 18 | } 19 | 20 | return electronExecPath; 21 | } 22 | -------------------------------------------------------------------------------- /packages/api/core/src/util/index.ts: -------------------------------------------------------------------------------- 1 | import { getElectronVersion, spawnPackageManager } from '@electron-forge/core-utils'; 2 | 3 | import { 4 | BuildIdentifierConfig, 5 | BuildIdentifierMap, 6 | fromBuildIdentifier, 7 | registerForgeConfigForDirectory, 8 | unregisterForgeConfigForDirectory, 9 | } from './forge-config'; 10 | 11 | import type { ForgeConfig } from '@electron-forge/shared-types'; 12 | 13 | export default class ForgeUtils { 14 | /** 15 | * Helper for creating a dynamic config value that will get its real value 16 | * based on the "buildIdentifier" in your Forge config. 17 | * 18 | * Usage: 19 | * `fromBuildIdentifier({ stable: 'App', beta: 'App Beta' })` 20 | */ 21 | fromBuildIdentifier(map: BuildIdentifierMap): BuildIdentifierConfig { 22 | return fromBuildIdentifier(map); 23 | } 24 | 25 | getElectronVersion = getElectronVersion; 26 | 27 | spawnPackageManager = spawnPackageManager; 28 | 29 | /** 30 | * Register a virtual config file for forge to find. 31 | * Takes precedence over other configuration options like a forge.config.js file. 32 | * Dir should point to the folder containing the app. 33 | */ 34 | registerForgeConfigForDirectory(dir: string, config: ForgeConfig): void { 35 | return registerForgeConfigForDirectory(dir, config); 36 | } 37 | 38 | /** 39 | * Unregister a forge config previously registered with registerForgeConfigForDirectory. 40 | */ 41 | unregisterForgeConfigForDirectory(dir: string): void { 42 | return unregisterForgeConfigForDirectory(dir); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/api/core/src/util/install-dependencies.ts: -------------------------------------------------------------------------------- 1 | import { PMDetails, spawnPackageManager } from '@electron-forge/core-utils'; 2 | import { ExitError } from '@malept/cross-spawn-promise'; 3 | import debug from 'debug'; 4 | 5 | const d = debug('electron-forge:dependency-installer'); 6 | 7 | export enum DepType { 8 | PROD = 'PROD', 9 | DEV = 'DEV', 10 | } 11 | 12 | export enum DepVersionRestriction { 13 | EXACT = 'EXACT', 14 | RANGE = 'RANGE', 15 | } 16 | 17 | export default async (pm: PMDetails, dir: string, deps: string[], depType = DepType.PROD, versionRestriction = DepVersionRestriction.RANGE): Promise => { 18 | d('installing', JSON.stringify(deps), 'in:', dir, `depType=${depType},versionRestriction=${versionRestriction},withPackageManager=${pm.executable}`); 19 | if (deps.length === 0) { 20 | d('nothing to install, stopping immediately'); 21 | return Promise.resolve(); 22 | } 23 | const cmd = [pm.install].concat(deps); 24 | if (depType === DepType.DEV) cmd.push(pm.dev); 25 | if (versionRestriction === DepVersionRestriction.EXACT) cmd.push(pm.exact); 26 | 27 | d('executing', JSON.stringify(cmd), 'in:', dir); 28 | try { 29 | await spawnPackageManager(pm, cmd, { 30 | cwd: dir, 31 | stdio: 'pipe', 32 | }); 33 | } catch (err) { 34 | if (err instanceof ExitError) { 35 | throw new Error(`Failed to install modules: ${JSON.stringify(deps)}\n\nWith output: ${err.message}\n${err.stderr ? err.stderr.toString() : ''}`); 36 | } else { 37 | throw err; 38 | } 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /packages/api/core/src/util/is-installed.ts: -------------------------------------------------------------------------------- 1 | export default function isInstalled(pkg: string): boolean { 2 | try { 3 | // eslint-disable-next-line @typescript-eslint/no-require-imports 4 | require(pkg); 5 | return true; 6 | } catch { 7 | // Package doesn't exist -- must not be installable on this platform 8 | return false; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/api/core/src/util/linux-installer.ts: -------------------------------------------------------------------------------- 1 | import { spawnSync } from 'node:child_process'; 2 | import { promisify } from 'node:util'; 3 | 4 | import sudoPrompt from 'sudo-prompt'; 5 | 6 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 7 | const which = async (type: string, prog: string, promise: () => Promise): Promise => { 8 | if (spawnSync('which', [prog]).status === 0) { 9 | await promise(); 10 | } else { 11 | throw new Error(`${prog} is required to install ${type} packages`); 12 | } 13 | }; 14 | 15 | export const sudo = (type: string, prog: string, args: string): Promise => 16 | which(type, prog, () => promisify(sudoPrompt.exec)(`${prog} ${args}`, { name: 'Electron Forge' })); 17 | 18 | export default which; 19 | -------------------------------------------------------------------------------- /packages/api/core/src/util/messages.ts: -------------------------------------------------------------------------------- 1 | export function info(interactive: boolean, message: string): void { 2 | if (interactive) { 3 | console.info(message); 4 | } 5 | } 6 | 7 | export function warn(interactive: boolean, message: string): void { 8 | if (interactive) { 9 | console.warn(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/api/core/src/util/out-dir.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { ResolvedForgeConfig } from '@electron-forge/shared-types'; 4 | 5 | const BASE_OUT_DIR = 'out'; 6 | 7 | export default (baseDir: string, forgeConfig: ResolvedForgeConfig): string => { 8 | const baseOutDir = forgeConfig.outDir || BASE_OUT_DIR; 9 | 10 | if (forgeConfig.buildIdentifier) { 11 | let identifier = forgeConfig.buildIdentifier; 12 | if (typeof identifier === 'function') { 13 | identifier = identifier(); 14 | } 15 | if (identifier) return path.resolve(baseDir, baseOutDir, identifier); 16 | } 17 | 18 | return path.resolve(baseDir, baseOutDir); 19 | }; 20 | -------------------------------------------------------------------------------- /packages/api/core/src/util/parse-archs.ts: -------------------------------------------------------------------------------- 1 | import { allOfficialArchsForPlatformAndVersion, SupportedPlatform } from '@electron/packager'; 2 | import { ForgeArch, ForgePlatform } from '@electron-forge/shared-types'; 3 | 4 | export default function parseArchs(platform: ForgePlatform | string, declaredArch: ForgeArch | 'all' | string, electronVersion: string): ForgeArch[] { 5 | if (declaredArch === 'all') { 6 | return allOfficialArchsForPlatformAndVersion(platform as SupportedPlatform, electronVersion) || ['x64']; 7 | } 8 | 9 | return declaredArch.split(',') as ForgeArch[]; 10 | } 11 | -------------------------------------------------------------------------------- /packages/api/core/src/util/read-package-json.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { ResolvedForgeConfig } from '@electron-forge/shared-types'; 4 | import fs from 'fs-extra'; 5 | 6 | import { runMutatingHook } from './hook'; 7 | 8 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 9 | export const readRawPackageJson = async (dir: string): Promise => fs.readJson(path.resolve(dir, 'package.json')); 10 | 11 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 12 | export const readMutatedPackageJson = async (dir: string, forgeConfig: ResolvedForgeConfig): Promise => 13 | runMutatingHook(forgeConfig, 'readPackageJson', await readRawPackageJson(dir)); 14 | -------------------------------------------------------------------------------- /packages/external/create-electron-app/README.md: -------------------------------------------------------------------------------- 1 | ## create-electron-app 2 | 3 | Create Electron App allows you to quickly bootstrap a new Electron app, using Electron Forge. 4 | 5 | ### Usage 6 | 7 | Initialize a new project by running the following: 8 | 9 | ```sh 10 | # yarn 1 11 | yarn create electron-app my-app 12 | 13 | # npm 14 | npx create-electron-app@latest my-app 15 | ``` 16 | 17 | You should now have a directory called my-app with an ultra-minimal Electron app boilerplate inside. If you head into that directory and start up the app, you'll be all set to start developing! 18 | 19 | ```sh 20 | # yarn 1 21 | cd my-app 22 | yarn start 23 | 24 | # npm 25 | cd my-app 26 | npm start 27 | ``` 28 | -------------------------------------------------------------------------------- /packages/external/create-electron-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-electron-app", 3 | "version": "7.8.1", 4 | "description": "Create Electron App", 5 | "main": "dist/index.js", 6 | "typings": "dist/index.d.ts", 7 | "author": "Samuel Attard", 8 | "license": "MIT", 9 | "dependencies": { 10 | "@electron-forge/cli": "7.8.1" 11 | }, 12 | "bin": { 13 | "create-electron-app": "dist/index.js" 14 | }, 15 | "files": [ 16 | "dist", 17 | "src" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /packages/external/create-electron-app/src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* eslint-disable */ 4 | import '@electron-forge/cli/dist/electron-forge-init'; 5 | -------------------------------------------------------------------------------- /packages/maker/appx/README.md: -------------------------------------------------------------------------------- 1 | ## maker-appx 2 | 3 | `@electron-forge/maker-appx` builds `.appx` packages, which are designed to target the Windows Store. 4 | 5 | You can only build the AppX target on Windows machines with the Windows 10 SDK installed. 6 | 7 | Configuration options are documented in [`MakerAppXConfig`](https://js.electronforge.io/interfaces/_electron_forge_maker_appx.MakerAppXConfig.html). 8 | 9 | ```javascript 10 | { 11 | name: '@electron-forge/maker-appx', 12 | config: { 13 | publisher: 'CN=developmentca', 14 | devCert: 'C:\\devcert.pfx', 15 | certPass: 'abcd' 16 | } 17 | } 18 | ``` 19 | -------------------------------------------------------------------------------- /packages/maker/appx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/maker-appx", 3 | "version": "7.8.1", 4 | "description": "AppX maker for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/MakerAppX.js", 9 | "typings": "dist/MakerAppX.d.ts", 10 | "devDependencies": { 11 | "vitest": "^3.1.3" 12 | }, 13 | "engines": { 14 | "node": ">= 16.4.0" 15 | }, 16 | "dependencies": { 17 | "@electron-forge/maker-base": "7.8.1", 18 | "@electron-forge/shared-types": "7.8.1", 19 | "cross-spawn": "^7.0.3", 20 | "fs-extra": "^10.0.0", 21 | "parse-author": "^2.0.0" 22 | }, 23 | "optionalDependencies": { 24 | "electron-windows-store": "^2.1.0" 25 | }, 26 | "publishConfig": { 27 | "access": "public" 28 | }, 29 | "files": [ 30 | "dist", 31 | "src" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /packages/maker/appx/spec/MakerAppX.spec.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs/promises'; 2 | import os from 'node:os'; 3 | import path from 'node:path'; 4 | 5 | import { afterAll, beforeAll, describe, expect, it } from 'vitest'; 6 | 7 | import { createDefaultCertificate } from '../src/MakerAppX'; 8 | 9 | describe.runIf(process.platform === 'win32')('MakerAppX', function () { 10 | describe('createDefaultCertificate', () => { 11 | let tmpDir: string; 12 | 13 | beforeAll(async () => { 14 | const tmp = os.tmpdir(); 15 | const tmpdir = path.join(tmp, 'electron-forge-test-'); 16 | tmpDir = await fs.mkdtemp(tmpdir); 17 | }); 18 | 19 | afterAll(async () => { 20 | await fs.rm(tmpDir, { recursive: true }); 21 | }); 22 | 23 | const def = process.platform === 'win32' ? it : it.skip; 24 | 25 | def('should create a .pfx file', async () => { 26 | await fs.copyFile(path.join(__dirname, '../../../api/core/spec/fixture', 'bogus-private-key.pvk'), path.join(tmpDir, 'dummy.pvk')); 27 | const outputCertPath = await createDefaultCertificate('CN=Test', { 28 | certFilePath: tmpDir, 29 | certFileName: 'dummy', 30 | install: false, 31 | }); 32 | 33 | const fileContents = await fs.readFile(outputCertPath); 34 | expect(fileContents).toBeInstanceOf(Buffer); 35 | expect(fileContents.length).toBeGreaterThan(0); 36 | }); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /packages/maker/appx/spec/util/author-name.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | 3 | import getNameFromAuthor from '../../src/util/author-name'; 4 | 5 | describe('getNameFromAuthor', () => { 6 | [ 7 | { 8 | author: 'First Last', 9 | expectedReturnValue: 'First Last', 10 | }, 11 | { 12 | author: 'First Last ', 13 | expectedReturnValue: 'First Last', 14 | }, 15 | { 16 | author: { 17 | name: 'First Last', 18 | }, 19 | expectedReturnValue: 'First Last', 20 | }, 21 | { 22 | author: undefined, 23 | expectedReturnValue: '', 24 | }, 25 | { 26 | author: '', 27 | expectedReturnValue: '', 28 | }, 29 | ].forEach((scenario) => { 30 | it(`${JSON.stringify(scenario.author)} -> "${scenario.expectedReturnValue}"`, () => { 31 | expect(getNameFromAuthor(scenario.author)).toBe(scenario.expectedReturnValue); 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /packages/maker/appx/src/Config.ts: -------------------------------------------------------------------------------- 1 | // TODO: Upstream this to electron-windows-store 2 | export interface MakerAppXConfig { 3 | containerVirtualization?: boolean; 4 | flatten?: boolean; 5 | packageVersion?: string; 6 | packageName?: string; 7 | packageDisplayName?: string; 8 | packageDescription?: string; 9 | packageExecutable?: string; 10 | assets?: string; 11 | manifest?: string; 12 | deploy?: boolean; 13 | publisher?: string; 14 | windowsKit?: string; 15 | devCert?: string; 16 | certPass?: string; 17 | desktopConverter?: string; 18 | expandedBaseImage?: string; 19 | makeappxParams?: string[]; 20 | signtoolParams?: string[]; 21 | makePri?: boolean; 22 | createConfigParams?: string[]; 23 | createPriParams?: string[]; 24 | finalSay?: () => Promise; 25 | 26 | // Magic Electron Forge Option 27 | makeVersionWinStoreCompatible?: boolean; 28 | } 29 | -------------------------------------------------------------------------------- /packages/maker/appx/src/util/author-name.ts: -------------------------------------------------------------------------------- 1 | import { PackagePerson } from '@electron-forge/shared-types'; 2 | import parseAuthor from 'parse-author'; 3 | 4 | export default function getNameFromAuthor(author: PackagePerson): string { 5 | let publisher: PackagePerson = author || ''; 6 | 7 | if (typeof publisher === 'string') { 8 | publisher = parseAuthor(publisher); 9 | } 10 | 11 | if (typeof publisher !== 'string' && publisher && typeof publisher.name === 'string') { 12 | publisher = publisher.name; 13 | } 14 | 15 | if (typeof publisher !== 'string') { 16 | publisher = ''; 17 | } 18 | 19 | return publisher; 20 | } 21 | -------------------------------------------------------------------------------- /packages/maker/appx/typings/ambient.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/maker/appx/typings/ambient.d.ts -------------------------------------------------------------------------------- /packages/maker/base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/maker-base", 3 | "version": "7.8.1", 4 | "description": "Base maker for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/Maker.js", 9 | "typings": "dist/Maker.d.ts", 10 | "devDependencies": { 11 | "vitest": "^3.1.3" 12 | }, 13 | "engines": { 14 | "node": ">= 16.4.0" 15 | }, 16 | "dependencies": { 17 | "@electron-forge/shared-types": "7.8.1", 18 | "fs-extra": "^10.0.0", 19 | "which": "^2.0.2" 20 | }, 21 | "publishConfig": { 22 | "access": "public" 23 | }, 24 | "files": [ 25 | "dist", 26 | "src" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /packages/maker/base/spec/config-fetcher.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it, vi } from 'vitest'; 2 | 3 | import { MakerBase } from '../src/Maker'; 4 | 5 | class MakerImpl extends MakerBase<{ a: number }> { 6 | name = 'test'; 7 | defaultPlatforms = []; 8 | } 9 | 10 | describe('prepareConfig', () => { 11 | it('should accept sync configure functions', async () => { 12 | const fetcher = vi.fn(); 13 | fetcher.mockReturnValue({ 14 | a: 123, 15 | }); 16 | const maker = new MakerImpl(fetcher, []); 17 | await maker.prepareConfig('x64'); 18 | expect(maker.config).toEqual({ 19 | a: 123, 20 | }); 21 | expect(fetcher).toHaveBeenCalledOnce(); 22 | expect(fetcher).toHaveBeenCalledWith('x64'); 23 | }); 24 | 25 | it('should accept async configure functions', async () => { 26 | const fetcher = vi.fn(); 27 | fetcher.mockResolvedValue({ 28 | a: 123, 29 | }); 30 | const maker = new MakerImpl(fetcher, []); 31 | await maker.prepareConfig('x64'); 32 | expect(maker.config).toEqual({ 33 | a: 123, 34 | }); 35 | expect(fetcher).toHaveBeenCalledOnce(); 36 | expect(fetcher).toHaveBeenCalledWith('x64'); 37 | }); 38 | 39 | it('should hand through the provided object', async () => { 40 | const maker = new MakerImpl( 41 | { 42 | a: 234, 43 | }, 44 | [] 45 | ); 46 | expect(maker.config).toBeUndefined(); 47 | await maker.prepareConfig('x64'); 48 | expect(maker.config).toEqual({ 49 | a: 234, 50 | }); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /packages/maker/base/spec/support.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | 3 | import { EmptyConfig, MakerBase } from '../src/Maker'; 4 | 5 | class MakerImpl extends MakerBase { 6 | name = 'test'; 7 | 8 | defaultPlatforms = []; 9 | 10 | requiredExternalBinaries = ['bash', 'nonexistent']; 11 | } 12 | 13 | describe('ensureExternalBinariesExist', () => { 14 | const maker = new MakerImpl({}, []); 15 | 16 | it('throws an error when one of the binaries does not exist', () => { 17 | expect(() => maker.ensureExternalBinariesExist()).toThrow(/the following external binaries need to be installed: bash, nonexistent/); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/maker/base/spec/version.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | 3 | import { EmptyConfig, MakerBase } from '../src/Maker'; 4 | 5 | class MakerImpl extends MakerBase { 6 | name = 'test'; 7 | 8 | defaultPlatforms = []; 9 | } 10 | 11 | describe('normalizeWindowsVersion', () => { 12 | const maker = new MakerImpl({}, []); 13 | 14 | it('removes everything after the dash', () => { 15 | for (const version of ['1.0.0-alpha', '1.0.0-alpha.1', '1.0.0-0.3.7', '1.0.0-x.7.z.92']) { 16 | expect(maker.normalizeWindowsVersion(version)).toEqual('1.0.0.0'); 17 | } 18 | }); 19 | it('removes everything after the plus sign', () => { 20 | for (const version of ['1.0.0-alpha+001', '1.0.0+20130313144700', '1.0.0-beta+exp.sha.5114f85', '1.0.0+21AF26D3----117B344092BD']) { 21 | expect(maker.normalizeWindowsVersion(version)).toEqual('1.0.0.0'); 22 | } 23 | }); 24 | it('does not truncate the version when there is no dash', () => { 25 | expect(maker.normalizeWindowsVersion('2.0.0')).toEqual('2.0.0.0'); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/maker/deb/README.md: -------------------------------------------------------------------------------- 1 | ## maker-deb 2 | 3 | `@electron-forge/maker-deb` builds .deb packages, which are the standard package format for Debian-based Linux distributions such as Ubuntu. You can only build the deb target on Linux or macOS machines with the fakeroot and dpkg packages installed. 4 | 5 | Configuration options are documented in [`MakerDebConfigOptions`](https://js.electronforge.io/interfaces/_electron_forge_maker_deb.InternalOptions.MakerDebConfigOptions.html). 6 | 7 | ```javascript 8 | { 9 | name: '@electron-forge/maker-deb', 10 | config: { 11 | options: { 12 | maintainer: 'The Forgers', 13 | homepage: 'https://example.com', 14 | icon: 'path/to/icon.svg' 15 | } 16 | } 17 | } 18 | ``` 19 | -------------------------------------------------------------------------------- /packages/maker/deb/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/maker-deb", 3 | "version": "7.8.1", 4 | "description": "Deb maker for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/MakerDeb.js", 9 | "typings": "dist/MakerDeb.d.ts", 10 | "devDependencies": { 11 | "@electron-forge/test-utils": "7.8.1", 12 | "vitest": "^3.1.3" 13 | }, 14 | "engines": { 15 | "node": ">= 16.4.0" 16 | }, 17 | "dependencies": { 18 | "@electron-forge/maker-base": "7.8.1", 19 | "@electron-forge/shared-types": "7.8.1" 20 | }, 21 | "optionalDependencies": { 22 | "electron-installer-debian": "^3.2.0" 23 | }, 24 | "publishConfig": { 25 | "access": "public" 26 | }, 27 | "files": [ 28 | "dist", 29 | "src" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /packages/maker/deb/src/MakerDeb.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { MakerBase, MakerOptions } from '@electron-forge/maker-base'; 4 | import { ForgeArch, ForgePlatform } from '@electron-forge/shared-types'; 5 | 6 | import { MakerDebConfig } from './Config'; 7 | 8 | export function debianArch(nodeArch: ForgeArch): string { 9 | switch (nodeArch) { 10 | case 'ia32': 11 | return 'i386'; 12 | case 'x64': 13 | return 'amd64'; 14 | case 'armv7l': 15 | return 'armhf'; 16 | case 'arm': 17 | return 'armel'; 18 | default: 19 | return nodeArch; 20 | } 21 | } 22 | 23 | export default class MakerDeb extends MakerBase { 24 | name = 'deb'; 25 | 26 | defaultPlatforms: ForgePlatform[] = ['linux']; 27 | 28 | requiredExternalBinaries: string[] = ['dpkg', 'fakeroot']; 29 | 30 | isSupportedOnCurrentPlatform(): boolean { 31 | return this.isInstalled('electron-installer-debian'); 32 | } 33 | 34 | async make({ dir, makeDir, targetArch }: MakerOptions): Promise { 35 | // eslint-disable-next-line n/no-missing-require 36 | const installer = require('electron-installer-debian'); 37 | 38 | const outDir = path.resolve(makeDir, 'deb', targetArch); 39 | 40 | await this.ensureDirectory(outDir); 41 | const { packagePaths } = await installer({ 42 | options: {}, 43 | ...this.config, 44 | arch: debianArch(targetArch), 45 | src: dir, 46 | dest: outDir, 47 | rename: undefined, 48 | }); 49 | 50 | return packagePaths; 51 | } 52 | } 53 | 54 | export { MakerDeb, MakerDebConfig }; 55 | -------------------------------------------------------------------------------- /packages/maker/dmg/README.md: -------------------------------------------------------------------------------- 1 | ## maker-dmg 2 | 3 | `@electron-forge/maker-dmg` builds `.dmg` files, which are the standard format for sharing macOS apps. You can only build the DMG target on macOS machines. 4 | 5 | Configuration options are documented in [`MakerDMGConfig`](https://js.electronforge.io/interfaces/_electron_forge_maker_dmg.MakerDMGConfig.html). 6 | 7 | ```javascript 8 | { 9 | name: '@electron-forge/maker-dmg', 10 | config: { 11 | background: './assets/dmg-background.png', 12 | format: 'ULFO' 13 | } 14 | } 15 | ``` 16 | -------------------------------------------------------------------------------- /packages/maker/dmg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/maker-dmg", 3 | "version": "7.8.1", 4 | "description": "DMG maker for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/MakerDMG.js", 9 | "typings": "dist/MakerDMG.d.ts", 10 | "devDependencies": { 11 | "@electron-forge/test-utils": "7.8.1", 12 | "vitest": "^3.1.3" 13 | }, 14 | "engines": { 15 | "node": ">= 16.4.0" 16 | }, 17 | "dependencies": { 18 | "@electron-forge/maker-base": "7.8.1", 19 | "@electron-forge/shared-types": "7.8.1", 20 | "fs-extra": "^10.0.0" 21 | }, 22 | "optionalDependencies": { 23 | "electron-installer-dmg": "^5.0.1" 24 | }, 25 | "publishConfig": { 26 | "access": "public" 27 | }, 28 | "files": [ 29 | "dist", 30 | "src" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /packages/maker/dmg/src/Config.ts: -------------------------------------------------------------------------------- 1 | import type { ElectronInstallerDMGOptions } from 'electron-installer-dmg'; 2 | 3 | export interface CodeSignOptions { 4 | 'signing-identity': string; 5 | identifier?: string; 6 | } 7 | 8 | export interface DMGContents { 9 | x: number; 10 | y: number; 11 | type: 'link' | 'file' | 'position'; 12 | path: string; 13 | name?: string; 14 | } 15 | 16 | export interface WindowPositionOptions { 17 | x: number; 18 | y: number; 19 | } 20 | 21 | export interface WindowSizeOptions { 22 | width: number; 23 | height: number; 24 | } 25 | 26 | export interface WindowOptions { 27 | position?: WindowPositionOptions; 28 | size?: WindowSizeOptions; 29 | } 30 | 31 | export interface AdditionalDMGOptions { 32 | 'background-color'?: string; 33 | 'icon-size'?: number; 34 | window?: WindowOptions; 35 | 'code-sign'?: CodeSignOptions; 36 | } 37 | 38 | export type MakerDMGConfig = Omit & { name?: string }; 39 | -------------------------------------------------------------------------------- /packages/maker/dmg/src/MakerDMG.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { MakerBase, MakerOptions } from '@electron-forge/maker-base'; 4 | import { ForgePlatform } from '@electron-forge/shared-types'; 5 | import fs from 'fs-extra'; 6 | 7 | import { MakerDMGConfig } from './Config'; 8 | 9 | import type { ElectronInstallerDMGOptions } from 'electron-installer-dmg'; 10 | 11 | export default class MakerDMG extends MakerBase { 12 | name = 'dmg'; 13 | 14 | defaultPlatforms: ForgePlatform[] = ['darwin', 'mas']; 15 | 16 | isSupportedOnCurrentPlatform(): boolean { 17 | return process.platform === 'darwin'; 18 | } 19 | 20 | async make({ dir, makeDir, appName, packageJSON, targetArch }: MakerOptions): Promise { 21 | const { createDMG } = require('electron-installer-dmg'); 22 | 23 | const outPath = path.resolve(makeDir, `${this.config.name || appName}.dmg`); 24 | const forgeDefaultOutPath = path.resolve(makeDir, `${appName}-${packageJSON.version}-${targetArch}.dmg`); 25 | 26 | await this.ensureFile(outPath); 27 | const dmgConfig: ElectronInstallerDMGOptions = { 28 | overwrite: true, 29 | name: appName, 30 | ...this.config, 31 | appPath: path.resolve(dir, `${appName}.app`), 32 | out: path.dirname(outPath), 33 | }; 34 | await createDMG(dmgConfig); 35 | if (!this.config.name) { 36 | await this.ensureFile(forgeDefaultOutPath); 37 | await fs.rename(outPath, forgeDefaultOutPath); 38 | return [forgeDefaultOutPath]; 39 | } 40 | 41 | return [outPath]; 42 | } 43 | } 44 | 45 | export { MakerDMG, MakerDMGConfig }; 46 | -------------------------------------------------------------------------------- /packages/maker/flatpak/README.md: -------------------------------------------------------------------------------- 1 | ## maker-flatpak 2 | 3 | `@electron-forge/maker-flatpak` [`.flatpak` files](http://flatpak.org/), which is a packaging format for Linux distributions that allows for sandboxed installation of applications in isolation from the rest of their system. 4 | 5 | You can only build the Flatpak target if you have `flatpak`, `flatpak-builder`, and `eu-strip` _\(usually part of the `elfutils` package\)_ installed on your system. 6 | 7 | Configuration options are documented in [`MakerFlatpakOptionsConfig`](https://js.electronforge.io/interfaces/_electron_forge_maker_flatpak.InternalOptions.MakerFlatpakOptionsConfig.html). 8 | 9 | ```javascript 10 | { 11 | name: '@electron-forge/maker-flatpak', 12 | config: { 13 | options: { 14 | categories: ['Video'], 15 | mimeType: ['video/h264'] 16 | } 17 | } 18 | } 19 | ``` 20 | -------------------------------------------------------------------------------- /packages/maker/flatpak/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/maker-flatpak", 3 | "version": "7.8.1", 4 | "description": "Flatpak maker for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/MakerFlatpak.js", 9 | "typings": "dist/MakerFlatpak.d.ts", 10 | "devDependencies": { 11 | "@electron-forge/test-utils": "7.8.1", 12 | "vitest": "^3.1.3" 13 | }, 14 | "engines": { 15 | "node": ">= 16.4.0" 16 | }, 17 | "dependencies": { 18 | "@electron-forge/maker-base": "7.8.1", 19 | "@electron-forge/shared-types": "7.8.1", 20 | "fs-extra": "^10.0.0" 21 | }, 22 | "optionalDependencies": { 23 | "@malept/electron-installer-flatpak": "^0.11.4" 24 | }, 25 | "publishConfig": { 26 | "access": "public" 27 | }, 28 | "files": [ 29 | "dist", 30 | "src" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /packages/maker/pkg/README.md: -------------------------------------------------------------------------------- 1 | ## maker-pkg 2 | 3 | `@electron-forge/maker-pkg` builds `.pkg` files for macOS. These are used to upload your application to the Mac App Store or just as an alternate distribution method for macOS users. You can only build the Pkg target on macOS machines while targeting the `darwin` or `mas` platforms. 4 | 5 | Configuration options are documented in [`MakerPkgConfig`](https://js.electronforge.io/interfaces/_electron_forge_maker_pkg.MakerPKGConfig.html). 6 | 7 | ```javascript 8 | { 9 | name: '@electron-forge/maker-pkg', 10 | config: { 11 | keychain: 'my-secret-ci-keychain' 12 | } 13 | } 14 | ``` 15 | -------------------------------------------------------------------------------- /packages/maker/pkg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/maker-pkg", 3 | "version": "7.8.1", 4 | "description": "PKG maker for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "license": "MIT", 7 | "main": "dist/MakerPKG.js", 8 | "typings": "dist/MakerPKG.d.ts", 9 | "devDependencies": { 10 | "@electron-forge/test-utils": "7.8.1", 11 | "vitest": "^3.1.3" 12 | }, 13 | "engines": { 14 | "node": ">= 16.4.0" 15 | }, 16 | "dependencies": { 17 | "@electron-forge/maker-base": "7.8.1", 18 | "@electron-forge/shared-types": "7.8.1", 19 | "@electron/osx-sign": "^1.0.5" 20 | }, 21 | "publishConfig": { 22 | "access": "public" 23 | }, 24 | "files": [ 25 | "dist", 26 | "src" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /packages/maker/pkg/src/Config.ts: -------------------------------------------------------------------------------- 1 | export interface MakerPKGConfig { 2 | /** 3 | * The application name. 4 | * 5 | * Default: `${appName}-${packageJSON.version}-${targetArch}`. 6 | */ 7 | name?: string; 8 | /** 9 | * Name of certificate to use when signing. 10 | * 11 | * Default to be selected with respect to platform from keychain or keychain 12 | * by system default. 13 | */ 14 | identity?: string; 15 | /** 16 | * Flag to enable/disable validation for signing identity. If enabled, the 17 | * identity provided will be validated in the keychain specified. 18 | * 19 | * Default: `true`. 20 | */ 21 | identityValidation?: boolean; 22 | /** 23 | * Path to install the bundle. Default to `/Applications`. 24 | */ 25 | install?: string; 26 | /** 27 | * The keychain name. 28 | * 29 | * Default: System default keychain. 30 | */ 31 | keychain?: string; 32 | /** 33 | * Path to a directory containing pre and/or post install scripts 34 | */ 35 | scripts?: string; 36 | } 37 | -------------------------------------------------------------------------------- /packages/maker/pkg/src/MakerPKG.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { flatAsync } from '@electron/osx-sign'; 4 | import { MakerBase, MakerOptions } from '@electron-forge/maker-base'; 5 | import { ForgePlatform } from '@electron-forge/shared-types'; 6 | 7 | import { MakerPKGConfig } from './Config'; 8 | 9 | export default class MakerPKG extends MakerBase { 10 | name = 'pkg'; 11 | 12 | defaultPlatforms: ForgePlatform[] = ['darwin', 'mas']; 13 | 14 | isSupportedOnCurrentPlatform(): boolean { 15 | return process.platform === 'darwin'; 16 | } 17 | 18 | async make({ dir, makeDir, appName, packageJSON, targetPlatform, targetArch }: MakerOptions): Promise { 19 | if (!this.isValidTargetPlatform(targetPlatform)) { 20 | throw new Error(`The pkg maker only supports targeting "mas" and "darwin" builds. You provided "${targetPlatform}".`); 21 | } 22 | 23 | const name = this.config.name || `${appName}-${packageJSON.version}-${targetArch}`; 24 | const outPath = path.resolve(makeDir, `${name}.pkg`); 25 | 26 | await this.ensureFile(outPath); 27 | 28 | const pkgConfig = { 29 | ...this.config, 30 | app: path.resolve(dir, `${appName}.app`), 31 | pkg: outPath, 32 | platform: targetPlatform, 33 | }; 34 | await flatAsync(pkgConfig); 35 | 36 | return [outPath]; 37 | } 38 | 39 | private isValidTargetPlatform(platform: string): platform is 'darwin' | 'mas' { 40 | return this.defaultPlatforms.includes(platform); 41 | } 42 | } 43 | 44 | export { MakerPKG, MakerPKGConfig }; 45 | -------------------------------------------------------------------------------- /packages/maker/rpm/README.md: -------------------------------------------------------------------------------- 1 | ## maker-rpm 2 | 3 | `@electron-forge/maker-rpm` builds `.rpm` files, which is the standard package format for RedHat-based Linux distributions such as Fedora. 4 | 5 | You can only build the RPM target on Linux machines with the `rpm` or `rpm-build` packages installed. 6 | 7 | Configuration options are documented in [`MakerRpmConfigOptions`](https://js.electronforge.io/interfaces/_electron_forge_maker_rpm.InternalOptions.MakerRpmConfigOptions.html). 8 | 9 | ```javascript 10 | { 11 | name: '@electron-forge/maker-rpm', 12 | config: { 13 | options: { 14 | name: 'QuickEdit', 15 | homepage: 'http://example.com' 16 | } 17 | } 18 | } 19 | ``` 20 | -------------------------------------------------------------------------------- /packages/maker/rpm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/maker-rpm", 3 | "version": "7.8.1", 4 | "description": "Rpm maker for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/MakerRpm.js", 9 | "typings": "dist/MakerRpm.d.ts", 10 | "devDependencies": { 11 | "@electron-forge/test-utils": "7.8.1", 12 | "vitest": "^3.1.3" 13 | }, 14 | "engines": { 15 | "node": ">= 16.4.0" 16 | }, 17 | "dependencies": { 18 | "@electron-forge/maker-base": "7.8.1", 19 | "@electron-forge/shared-types": "7.8.1" 20 | }, 21 | "optionalDependencies": { 22 | "electron-installer-redhat": "^3.2.0" 23 | }, 24 | "publishConfig": { 25 | "access": "public" 26 | }, 27 | "files": [ 28 | "dist", 29 | "src" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /packages/maker/snap/README.md: -------------------------------------------------------------------------------- 1 | ## maker-snap 2 | 3 | `@electron-forge/maker-snap` builds `.snap` files, which is the packaging format created and sponsored by Canonical, the company behind Ubuntu. It is a sandboxed package format that lets users of various Linux distributions install your application in an isolated environment on their machine. 4 | 5 | You can only build the Snapcraft target on Linux systems with the `snapcraft` package installed. 6 | 7 | ```javascript 8 | { 9 | name: '@electron-forge/maker-snap', 10 | config: { 11 | version: '1.1.0', 12 | features: { 13 | audio: true, 14 | mpris: 'com.example.mpris', 15 | webgl: true 16 | }, 17 | summary: 'My application' 18 | } 19 | } 20 | ``` 21 | -------------------------------------------------------------------------------- /packages/maker/snap/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/maker-snap", 3 | "version": "7.8.1", 4 | "description": "Snap maker for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "license": "MIT", 7 | "main": "dist/MakerSnap.js", 8 | "typings": "dist/MakerSnap.d.ts", 9 | "devDependencies": { 10 | "@electron-forge/test-utils": "7.8.1", 11 | "vitest": "^3.1.3" 12 | }, 13 | "engines": { 14 | "node": ">= 16.4.0" 15 | }, 16 | "dependencies": { 17 | "@electron-forge/maker-base": "7.8.1", 18 | "@electron-forge/shared-types": "7.8.1" 19 | }, 20 | "optionalDependencies": { 21 | "electron-installer-snap": "^5.2.0" 22 | }, 23 | "publishConfig": { 24 | "access": "public" 25 | }, 26 | "files": [ 27 | "dist", 28 | "src" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /packages/maker/snap/src/Config.ts: -------------------------------------------------------------------------------- 1 | import { Options, SnapcraftConfig } from 'electron-installer-snap'; 2 | 3 | export type MakerSnapConfig = Omit & SnapcraftConfig; 4 | -------------------------------------------------------------------------------- /packages/maker/snap/src/MakerSnap.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { MakerBase, MakerOptions } from '@electron-forge/maker-base'; 4 | import { ForgePlatform } from '@electron-forge/shared-types'; 5 | 6 | import { MakerSnapConfig } from './Config'; 7 | 8 | export default class MakerSnap extends MakerBase { 9 | name = 'snap'; 10 | 11 | defaultPlatforms: ForgePlatform[] = ['linux']; 12 | 13 | requiredExternalBinaries: string[] = ['snapcraft']; 14 | 15 | isSupportedOnCurrentPlatform(): boolean { 16 | return process.platform === 'linux'; 17 | } 18 | 19 | async make({ dir, makeDir, targetArch }: MakerOptions): Promise { 20 | const installer = require('electron-installer-snap'); 21 | 22 | const outPath = path.resolve(makeDir, 'snap', targetArch); 23 | 24 | await this.ensureDirectory(outPath); 25 | 26 | const snapDefaults = { 27 | arch: targetArch, 28 | dest: outPath, 29 | src: dir, 30 | }; 31 | const snapConfig = { ...this.config, ...snapDefaults }; 32 | 33 | return [await installer(snapConfig)]; 34 | } 35 | } 36 | 37 | export { MakerSnap, MakerSnapConfig }; 38 | -------------------------------------------------------------------------------- /packages/maker/squirrel/README.md: -------------------------------------------------------------------------------- 1 | ## maker-squirrel 2 | 3 | `@electron-forge/maker-squirrel` builds a number of files required to distribute apps using the Squirrel.Windows framework. It generates a `{appName} Setup.exe` file which is the main installer for your application, `{appName}-full.nupkg` and a `RELEASES` file which you use to issue updates to your application. 4 | 5 | Pre-requisites: 6 | 7 | * Windows machine 8 | * Linux machine with `mono` and `wine` installed. 9 | 10 | Configuration options are documented in [`MakerSquirrelConfigOptions`](https://js.electronforge.io/interfaces/_electron_forge_maker_squirrel.InternalOptions.Options.html). 11 | 12 | ```javascript 13 | { 14 | name: '@electron-forge/maker-squirrel', 15 | config: { 16 | certificateFile: './cert.pfx', 17 | certificatePassword: 'this-is-a-secret' 18 | } 19 | } 20 | ``` 21 | -------------------------------------------------------------------------------- /packages/maker/squirrel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/maker-squirrel", 3 | "version": "7.8.1", 4 | "description": "Squirrel maker for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/MakerSquirrel.js", 9 | "typings": "dist/MakerSquirrel.d.ts", 10 | "engines": { 11 | "node": ">= 16.4.0" 12 | }, 13 | "dependencies": { 14 | "@electron-forge/maker-base": "7.8.1", 15 | "@electron-forge/shared-types": "7.8.1", 16 | "fs-extra": "^10.0.0" 17 | }, 18 | "optionalDependencies": { 19 | "electron-winstaller": "^5.3.0" 20 | }, 21 | "publishConfig": { 22 | "access": "public" 23 | }, 24 | "files": [ 25 | "dist", 26 | "src" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /packages/maker/wix/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## maker-wix-msi 3 | 4 | The WiX MSI target builds `.msi` files, which are "traditional" Windows installer files. 5 | 6 | Pre-requisites: 7 | 8 | * `light` and `candle` installed from [the WiX toolkit](https://github.com/felixrieseberg/electron-wix-msi#prerequisites). 9 | 10 | Configuration options are documented in [`MakerWixConfig`](https://js.electronforge.io/interfaces/_electron_forge_maker_wix.MakerWixConfig.html). 11 | 12 | ```javascript 13 | { 14 | name: '@electron-forge/maker-wix', 15 | config: { 16 | language: 1033, 17 | manufacturer: 'My Awesome Company' 18 | } 19 | } 20 | ``` 21 | -------------------------------------------------------------------------------- /packages/maker/wix/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/maker-wix", 3 | "version": "7.8.1", 4 | "description": "Wix maker for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/MakerWix.js", 9 | "typings": "dist/MakerWix.d.ts", 10 | "devDependencies": { 11 | "vitest": "^3.1.3" 12 | }, 13 | "engines": { 14 | "node": ">= 16.4.0" 15 | }, 16 | "dependencies": { 17 | "@electron-forge/maker-base": "7.8.1", 18 | "@electron-forge/shared-types": "7.8.1", 19 | "chalk": "^4.0.0", 20 | "electron-wix-msi": "^5.1.3", 21 | "log-symbols": "^4.0.0", 22 | "parse-author": "^2.0.0", 23 | "semver": "^7.2.1" 24 | }, 25 | "publishConfig": { 26 | "access": "public" 27 | }, 28 | "files": [ 29 | "dist", 30 | "src" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /packages/maker/wix/spec/author-name.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | 3 | import getNameFromAuthor from '../src/util/author-name'; 4 | 5 | describe('author-name', () => { 6 | describe('getNameFromAuthor', () => { 7 | [ 8 | { 9 | author: 'First Last', 10 | expectedReturnValue: 'First Last', 11 | }, 12 | { 13 | author: 'First Last ', 14 | expectedReturnValue: 'First Last', 15 | }, 16 | { 17 | author: { 18 | name: 'First Last', 19 | }, 20 | expectedReturnValue: 'First Last', 21 | }, 22 | { 23 | author: undefined, 24 | expectedReturnValue: '', 25 | }, 26 | { 27 | author: '', 28 | expectedReturnValue: '', 29 | }, 30 | ].forEach((scenario) => { 31 | it(`${JSON.stringify(scenario.author)} -> "${scenario.expectedReturnValue}"`, () => { 32 | expect(getNameFromAuthor(scenario.author)).toEqual(scenario.expectedReturnValue); 33 | }); 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /packages/maker/wix/src/Config.ts: -------------------------------------------------------------------------------- 1 | import { MSICreator, MSICreatorOptions } from 'electron-wix-msi/lib/creator'; 2 | 3 | export type MakerWixConfig = Omit & { 4 | /** 5 | * The app's description 6 | * 7 | * @defaultValue The `description` field in package.json 8 | */ 9 | description?: string; 10 | /** 11 | * The app's name. 12 | * 13 | * @defaultValue The value of `packagerConfig.name` in the Forge config, or the `productName` or `name` in package.json (in that order) 14 | */ 15 | name?: string; 16 | /** 17 | * The app's version. It must be a valid semantic version. 18 | * 19 | * @defaultValue The `version` field in package.json 20 | */ 21 | version?: string; 22 | /** 23 | * The app's manufacturer 24 | * 25 | * @defaultValue The `author` field in package.json 26 | */ 27 | manufacturer?: string; 28 | /** 29 | * The name of the exe file 30 | * 31 | * @defaultValue the default {@link MakerWixConfig.name} + `.exe` 32 | */ 33 | exe?: string; 34 | /** 35 | * Allows for the modification of the MSICreator before create is called. 36 | */ 37 | beforeCreate?: (creator: MSICreator) => Promise | void; 38 | }; 39 | -------------------------------------------------------------------------------- /packages/maker/wix/src/util/author-name.ts: -------------------------------------------------------------------------------- 1 | import { PackagePerson } from '@electron-forge/shared-types'; 2 | import parseAuthor from 'parse-author'; 3 | 4 | export default function getNameFromAuthor(author: PackagePerson): string { 5 | let publisher: PackagePerson = author || ''; 6 | 7 | if (typeof publisher === 'string') { 8 | publisher = parseAuthor(publisher); 9 | } 10 | 11 | if (typeof publisher !== 'string' && publisher && typeof publisher.name === 'string') { 12 | publisher = publisher.name; 13 | } 14 | 15 | if (typeof publisher !== 'string') { 16 | publisher = ''; 17 | } 18 | 19 | return publisher; 20 | } 21 | -------------------------------------------------------------------------------- /packages/maker/wix/typings/ambient.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/maker/wix/typings/ambient.d.ts -------------------------------------------------------------------------------- /packages/maker/zip/README.md: -------------------------------------------------------------------------------- 1 | ## maker-zip 2 | 3 | `@electron-forge/maker-zip` builds basic `.zip` files containing your packaged application. There are no platform specific dependencies for using this maker and it will run on any platform. 4 | 5 | Note: There are no configuration options for this target. 6 | 7 | ```javascript 8 | { 9 | name: '@electron-forge/maker-zip' 10 | } 11 | ``` 12 | -------------------------------------------------------------------------------- /packages/maker/zip/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/maker-zip", 3 | "version": "7.8.1", 4 | "description": "ZIP maker for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/MakerZIP.js", 9 | "typings": "dist/MakerZIP.d.ts", 10 | "devDependencies": { 11 | "@electron-forge/test-utils": "7.8.1", 12 | "vitest": "^3.1.3" 13 | }, 14 | "engines": { 15 | "node": ">= 16.4.0" 16 | }, 17 | "dependencies": { 18 | "@electron-forge/maker-base": "7.8.1", 19 | "@electron-forge/shared-types": "7.8.1", 20 | "cross-zip": "^4.0.0", 21 | "fs-extra": "^10.0.0", 22 | "got": "^11.8.5" 23 | }, 24 | "publishConfig": { 25 | "access": "public" 26 | }, 27 | "files": [ 28 | "dist", 29 | "src" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /packages/maker/zip/spec/fixture/fake-app/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/maker/zip/spec/fixture/fake-app/index.js -------------------------------------------------------------------------------- /packages/maker/zip/spec/fixture/fake-darwin-app/My Test App.app/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/maker/zip/spec/fixture/fake-darwin-app/My Test App.app/index.js -------------------------------------------------------------------------------- /packages/maker/zip/src/Config.ts: -------------------------------------------------------------------------------- 1 | export interface MakerZIPConfig { 2 | /** 3 | * A URL to the directory containing your existing macOS auto-update 4 | * RELEASES.json file. If given this maker will download the existing 5 | * file and add this release to it, also setting the "currentRelease" to 6 | * this release. 7 | * 8 | * For instance if your URL is "https://update.example.com/my-app/darwin/x64/RELEASES.json" 9 | * you should provide "https://update.example.com/my-app/darwin/x64". This logic assumes 10 | * that you published your files using a forge publisher compatible with the auto updater (e.g. S3). 11 | * 12 | * Publishing this RELEASES.json will result in clients downloading this version 13 | * as an update. 14 | * 15 | * If this option is not set no RELEASES.json file will be generated. 16 | */ 17 | macUpdateManifestBaseUrl?: string; 18 | /** 19 | * Only used if `squirrelMacManifestBaseUrl` is provided. Used to populate 20 | * the "notes" field of the releases manifest for macOS updates. 21 | */ 22 | macUpdateReleaseNotes?: string; 23 | } 24 | -------------------------------------------------------------------------------- /packages/plugin/auto-unpack-natives/README.md: -------------------------------------------------------------------------------- 1 | ## plugin-auto-unpack-natives 2 | 3 | This plugin will automatically add all native Node modules in your node_modules folder to the `asar.unpack` config option in your `packagerConfig`. If your app uses native Node modules, you should probably use this to reduce loading times and disk consumption on your users' machines. 4 | 5 | ```javascript 6 | // forge.config.js 7 | 8 | module.exports = { 9 | plugins: [ 10 | { 11 | name: '@electron-forge/plugin-auto-unpack-natives', 12 | config: {} 13 | } 14 | ] 15 | }; 16 | ``` 17 | -------------------------------------------------------------------------------- /packages/plugin/auto-unpack-natives/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/plugin-auto-unpack-natives", 3 | "version": "7.8.1", 4 | "description": "Auto Unpack Natives plugin for Electron Forge, automatically adds native node modules to asar.unpacked", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/AutoUnpackNativesPlugin.js", 9 | "typings": "dist/AutoUnpackNativesPlugin.d.ts", 10 | "engines": { 11 | "node": ">= 16.4.0" 12 | }, 13 | "dependencies": { 14 | "@electron-forge/plugin-base": "7.8.1", 15 | "@electron-forge/shared-types": "7.8.1" 16 | }, 17 | "publishConfig": { 18 | "access": "public" 19 | }, 20 | "files": [ 21 | "dist", 22 | "src" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /packages/plugin/auto-unpack-natives/src/AutoUnpackNativesPlugin.ts: -------------------------------------------------------------------------------- 1 | import { PluginBase } from '@electron-forge/plugin-base'; 2 | import { ForgeHookFn, ForgeHookMap } from '@electron-forge/shared-types'; 3 | 4 | import { AutoUnpackNativesConfig } from './Config'; 5 | 6 | export default class AutoUnpackNativesPlugin extends PluginBase { 7 | name = 'auto-unpack-natives'; 8 | 9 | getHooks(): ForgeHookMap { 10 | return { 11 | resolveForgeConfig: this.resolveForgeConfig, 12 | }; 13 | } 14 | 15 | resolveForgeConfig: ForgeHookFn<'resolveForgeConfig'> = async (forgeConfig) => { 16 | if (!forgeConfig.packagerConfig) { 17 | forgeConfig.packagerConfig = {}; 18 | } 19 | if (!forgeConfig.packagerConfig.asar) { 20 | throw new Error('The AutoUnpackNatives plugin requires asar to be truthy or an object'); 21 | } 22 | if (forgeConfig.packagerConfig.asar === true) { 23 | forgeConfig.packagerConfig.asar = {}; 24 | } 25 | const existingUnpack = forgeConfig.packagerConfig.asar.unpack; 26 | const newUnpack = '**/{.**,**}/**/*.node'; 27 | if (existingUnpack) { 28 | forgeConfig.packagerConfig.asar.unpack = `{${existingUnpack},${newUnpack}}`; 29 | } else { 30 | forgeConfig.packagerConfig.asar.unpack = newUnpack; 31 | } 32 | return forgeConfig; 33 | }; 34 | } 35 | 36 | export { AutoUnpackNativesPlugin, AutoUnpackNativesConfig }; 37 | -------------------------------------------------------------------------------- /packages/plugin/auto-unpack-natives/src/Config.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-empty-object-type 2 | export interface AutoUnpackNativesConfig { 3 | // No configuration options 4 | } 5 | -------------------------------------------------------------------------------- /packages/plugin/base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/plugin-base", 3 | "version": "7.8.1", 4 | "description": "Base plugin for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/Plugin.js", 9 | "typings": "dist/Plugin.d.ts", 10 | "engines": { 11 | "node": ">= 16.4.0" 12 | }, 13 | "dependencies": { 14 | "@electron-forge/shared-types": "7.8.1" 15 | }, 16 | "publishConfig": { 17 | "access": "public" 18 | }, 19 | "files": [ 20 | "dist", 21 | "src" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /packages/plugin/electronegativity/README.md: -------------------------------------------------------------------------------- 1 | ## plugin-electronegativity 2 | 3 | The Electronegativity plugin integrates Doyensec's Electronegativity tool into the Electron Forge workflow. After packaging your Electron app, it identifies any known misconfigurations and security anti-patterns. 4 | 5 | ```javascript 6 | // forge.config.js 7 | 8 | module.exports = { 9 | plugins: [ 10 | [ 11 | '@electron-forge/plugin-electronegativity', 12 | { 13 | isSarif: true 14 | } 15 | ] 16 | ] 17 | }; 18 | ``` 19 | -------------------------------------------------------------------------------- /packages/plugin/electronegativity/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/plugin-electronegativity", 3 | "version": "7.8.1", 4 | "description": "Integrate Electronegativity into the Electron Forge workflow", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/electron/forge", 8 | "directory": "packages/plugin/electronegativity" 9 | }, 10 | "author": "Mark Lee", 11 | "license": "MIT", 12 | "main": "dist/ElectronegativityPlugin.js", 13 | "typings": "dist/ElectronegativityPlugin.d.ts", 14 | "engines": { 15 | "node": ">= 16.4.0" 16 | }, 17 | "dependencies": { 18 | "@doyensec/electronegativity": "^1.9.1", 19 | "@electron-forge/plugin-base": "7.8.1", 20 | "@electron-forge/shared-types": "7.8.1" 21 | }, 22 | "publishConfig": { 23 | "access": "public" 24 | }, 25 | "files": [ 26 | "dist", 27 | "src" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /packages/plugin/fuses/README.md: -------------------------------------------------------------------------------- 1 | ## @electron-forge/plugin-fuses 2 | 3 | This plugin allows flipping [Electron Fuses](https://github.com/electron/fuses) when packaging your app with Electron Forge. 4 | 5 | ### Usage 6 | 7 | Install `@electron-forge/plugin-fuses` and `@electron/fuses` as dev dependencies and add this plugin to the `plugins` array in your Forge configuration: 8 | 9 | ```shell 10 | # Yarn 11 | yarn add --dev @electron-forge/plugin-fuses @electron/fuses 12 | 13 | # npm 14 | npm i -D @electron-forge/plugin-fuses @electron/fuses 15 | ``` 16 | 17 | ```js 18 | // forge.config.js 19 | 20 | const { FusesPlugin } = require('@electron-forge/plugin-fuses'); 21 | const { FuseV1Options, FuseVersion } = require('@electron/fuses'); 22 | 23 | const forgeConfig = { 24 | plugins: [ 25 | new FusesPlugin({ 26 | version: FuseVersion.V1, 27 | [FuseV1Options.RunAsNode]: false 28 | // ...any other options supported by @electron/fuses 29 | }) 30 | ] 31 | }; 32 | 33 | module.exports = forgeConfig; 34 | ``` 35 | -------------------------------------------------------------------------------- /packages/plugin/fuses/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/plugin-fuses", 3 | "version": "7.8.1", 4 | "description": "A plugin for flipping Electron Fuses in Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Erik Moura ", 7 | "license": "MIT", 8 | "main": "dist/FusesPlugin.js", 9 | "files": [ 10 | "dist", 11 | "src", 12 | "package.json", 13 | "README.md" 14 | ], 15 | "typings": "dist/FusesPlugin.d.ts", 16 | "devDependencies": { 17 | "@electron/fuses": ">=1.0.0", 18 | "@malept/cross-spawn-promise": "^2.0.0", 19 | "xvfb-maybe": "^0.2.1" 20 | }, 21 | "peerDependencies": { 22 | "@electron/fuses": ">=1.0.0" 23 | }, 24 | "engines": { 25 | "node": ">= 16.4.0" 26 | }, 27 | "dependencies": { 28 | "@electron-forge/plugin-base": "7.8.1", 29 | "@electron-forge/shared-types": "7.8.1" 30 | }, 31 | "publishConfig": { 32 | "access": "public" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/plugin/fuses/spec/fixture/app/forge.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | 3 | import { FuseV1Options, FuseVersion } from '@electron/fuses'; 4 | import { FusesPlugin } from '@electron-forge/plugin-fuses'; 5 | import { ForgeConfig } from '@electron-forge/shared-types'; 6 | import fsExtra from 'fs-extra'; 7 | 8 | const forgeConfig: ForgeConfig = { 9 | packagerConfig: { 10 | afterComplete: [ 11 | // makes tests a bit simpler by having a single output directory in every platform/arch 12 | async (packagedAppLocation, _electronVersion, _targetPlatform, _targetArch, done) => { 13 | const parentDir = path.resolve(packagedAppLocation, '..'); 14 | await fsExtra.move(packagedAppLocation, path.join(parentDir, 'fuses-test-app'), { 15 | overwrite: true, 16 | }); 17 | 18 | done(); 19 | }, 20 | ], 21 | }, 22 | 23 | plugins: [ 24 | new FusesPlugin({ 25 | version: FuseVersion.V1, 26 | [FuseV1Options.RunAsNode]: false, 27 | }), 28 | ], 29 | }; 30 | 31 | export default forgeConfig; 32 | -------------------------------------------------------------------------------- /packages/plugin/fuses/spec/fixture/app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fuses-test-app", 3 | "version": "1.0.0", 4 | "main": "./src/main.js", 5 | "scripts": { 6 | "package": "electron-forge package" 7 | }, 8 | "dependencies": { 9 | "@electron/fuses": "^1.6.1", 10 | "fs-extra": "^10.0.0" 11 | }, 12 | "devDependencies": { 13 | "@electron-forge/cli": "6.4.0", 14 | "@electron-forge/plugin-fuses": "6.4.0", 15 | "@electron-forge/shared-types": "6.4.0", 16 | "electron": "34.0.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/plugin/fuses/spec/fixture/app/package.json.tmpl: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fuses-test-app", 3 | "version": "1.0.0", 4 | "main": "./src/main.js", 5 | "scripts": { 6 | "package": "electron-forge package" 7 | }, 8 | "dependencies": { 9 | "@electron/fuses": "^1.6.1", 10 | "fs-extra": "^10.0.0" 11 | }, 12 | "devDependencies": { 13 | "@electron-forge/cli": "6.4.0", 14 | "@electron-forge/plugin-fuses": "6.4.0", 15 | "@electron-forge/shared-types": "6.4.0", 16 | "electron": "34.0.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/plugin/fuses/spec/fixture/app/src/main.js: -------------------------------------------------------------------------------- 1 | const { app } = require('electron'); 2 | 3 | console.log('The Fuses plugin is working'); 4 | 5 | app.exit(0); 6 | -------------------------------------------------------------------------------- /packages/plugin/fuses/src/util/getElectronExecutablePath.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { ForgePlatform } from '@electron-forge/shared-types'; 4 | 5 | type GetElectronExecutablePathParams = { 6 | appName: string; 7 | basePath: string; 8 | platform: ForgePlatform; 9 | }; 10 | 11 | export function getElectronExecutablePath({ appName, basePath, platform }: GetElectronExecutablePathParams): string { 12 | if (['darwin', 'mas'].includes(platform)) { 13 | return path.join(basePath, 'MacOS', appName); 14 | } 15 | 16 | const suffix = platform === 'win32' ? '.exe' : ''; 17 | return path.join(basePath, `${appName}${suffix}`); 18 | } 19 | -------------------------------------------------------------------------------- /packages/plugin/local-electron/README.md: -------------------------------------------------------------------------------- 1 | ## plugin-local-electron 2 | 3 | This plugin allows you to both run and build your app using a local build of Electron. This can be incredibly useful if you want to test a feature or a bug fix in your app before making a PR up to the Electron repository. 4 | 5 | _Note: This plugin should only be used by people who are building Electron locally themselves. If you want to set up a local build of Electron, you should check out [Electron Build Tools](https://github.com/electron/build-tools)._ 6 | 7 | ```javascript 8 | // forge.config.js 9 | 10 | module.exports = { 11 | plugins: [ 12 | { 13 | name: '@electron-forge/plugin-local-electron', 14 | config: { 15 | electronPath: '/Users/me/projects/electron/out/Testing' 16 | } 17 | } 18 | ] 19 | }; 20 | ``` 21 | -------------------------------------------------------------------------------- /packages/plugin/local-electron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/plugin-local-electron", 3 | "version": "7.8.1", 4 | "description": "Local Electron plugin for Electron Forge, let's you use a local build of Electron", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/LocalElectronPlugin.js", 9 | "typings": "dist/LocalElectronPlugin.d.ts", 10 | "engines": { 11 | "node": ">= 16.4.0" 12 | }, 13 | "dependencies": { 14 | "@electron-forge/plugin-base": "7.8.1", 15 | "@electron-forge/shared-types": "7.8.1", 16 | "fs-extra": "^10.0.0" 17 | }, 18 | "devDependencies": { 19 | "vitest": "^3.1.3" 20 | }, 21 | "publishConfig": { 22 | "access": "public" 23 | }, 24 | "files": [ 25 | "dist", 26 | "src" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /packages/plugin/local-electron/src/Config.ts: -------------------------------------------------------------------------------- 1 | export interface LocalElectronPluginConfig { 2 | /** 3 | * Whether or not the plugin is enabled. 4 | * 5 | * Can be handy to set this to an environment variable for quick personal 6 | * toggling of this plugin. 7 | * 8 | * Default: `true` 9 | */ 10 | enabled?: boolean; 11 | /** 12 | * An absolute path to the folder containing your built version of Electron. 13 | * 14 | * Normally this looks like `/path/to/electron/out/D` 15 | */ 16 | electronPath: string; 17 | /** 18 | * The platform your local build of Electron is for. You only need to set 19 | * this if you have a local build for a platform that isn't your system's 20 | * platform. 21 | * 22 | * Default: process.platform 23 | */ 24 | electronPlatform?: string; 25 | /** 26 | * The arch your local build of Electron is for. You only need to set this if 27 | * you have a local build for an arch that isn't your system's arch. 28 | * 29 | * Default: process.arch 30 | */ 31 | electronArch?: string; 32 | } 33 | -------------------------------------------------------------------------------- /packages/plugin/vite/README.md: -------------------------------------------------------------------------------- 1 | ## plugin-vite 2 | 3 | _Note: This plugin is considered experimental and is under active development; we do not offer API stability guarantees as development continues. Minor versions may include breaking changes - see release notes for details on migration._ 4 | 5 | This plugin makes it easy to set up standard vite tooling to compile both your main process code and your renderer process code, with built-in support for Hot Module Replacement (HMR) in the renderer process and support for multiple renderers. 6 | 7 | ```javascript 8 | // forge.config.js 9 | 10 | module.exports = { 11 | plugins: [ 12 | { 13 | name: '@electron-forge/plugin-vite', 14 | config: { 15 | // `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc. 16 | // If you are familiar with Vite configuration, it will look really familiar. 17 | build: [ 18 | { 19 | // `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`. 20 | entry: 'src/main.js', 21 | config: 'vite.main.config.mjs' 22 | }, 23 | { 24 | entry: 'src/preload.js', 25 | config: 'vite.preload.config.mjs' 26 | } 27 | ], 28 | renderer: [ 29 | { 30 | name: 'main_window', 31 | config: 'vite.renderer.config.mjs' 32 | } 33 | ] 34 | } 35 | } 36 | ] 37 | }; 38 | ``` 39 | -------------------------------------------------------------------------------- /packages/plugin/vite/forge-vite-env.d.ts: -------------------------------------------------------------------------------- 1 | export {}; // Make this a module 2 | import type { VitePluginConfig } from './src/Config'; 3 | 4 | declare global { 5 | // This allows TypeScript to pick up the magic constants that's auto-generated by Forge's Vite 6 | // plugin that tells the Electron app where to look for the Vite-bundled app code (depending on 7 | // whether you're running in development or production). 8 | const MAIN_WINDOW_VITE_DEV_SERVER_URL: string; 9 | const MAIN_WINDOW_VITE_NAME: string; 10 | 11 | interface VitePluginRuntimeKeys { 12 | VITE_DEV_SERVER_URL: `${string}_VITE_DEV_SERVER_URL`; 13 | VITE_NAME: `${string}_VITE_NAME`; 14 | } 15 | } 16 | 17 | declare module 'vite' { 18 | interface ConfigEnv { 19 | root: string; 20 | forgeConfig: VitePluginConfig; 21 | forgeConfigSelf: VitePluginConfig[K][number]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/plugin/vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/plugin-vite", 3 | "version": "7.8.1", 4 | "description": "Vite plugin for Electron Forge, lets you use Vite directly in your tooling", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/electron/forge", 8 | "directory": "packages/plugin/vite" 9 | }, 10 | "author": "caoxiemeihao", 11 | "license": "MIT", 12 | "main": "dist/VitePlugin.js", 13 | "typings": "dist/VitePlugin.d.ts", 14 | "dependencies": { 15 | "@electron-forge/core-utils": "7.8.1", 16 | "@electron-forge/plugin-base": "7.8.1", 17 | "@electron-forge/shared-types": "7.8.1", 18 | "@electron-forge/web-multi-logger": "7.8.1", 19 | "chalk": "^4.0.0", 20 | "debug": "^4.3.1", 21 | "fs-extra": "^10.0.0", 22 | "listr2": "^7.0.2" 23 | }, 24 | "devDependencies": { 25 | "@electron/packager": "^18.3.5", 26 | "@malept/cross-spawn-promise": "^2.0.0", 27 | "@types/node": "^18.0.3", 28 | "vite": "^5.0.12", 29 | "vitest": "^3.1.3", 30 | "which": "^2.0.2", 31 | "xvfb-maybe": "^0.2.1" 32 | }, 33 | "engines": { 34 | "node": ">= 16.4.0" 35 | }, 36 | "publishConfig": { 37 | "access": "public" 38 | }, 39 | "files": [ 40 | "dist", 41 | "src", 42 | "forge-vite-env.d.ts" 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /packages/plugin/vite/spec/fixtures/.gitignore: -------------------------------------------------------------------------------- 1 | # lockfile 2 | package-lock.json 3 | pnpm-lock.yaml 4 | yarn.lock 5 | -------------------------------------------------------------------------------- /packages/plugin/vite/spec/fixtures/vite-configs/vite.main.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default {}; 3 | -------------------------------------------------------------------------------- /packages/plugin/vite/spec/fixtures/vite-configs/vite.preload.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default {}; 3 | -------------------------------------------------------------------------------- /packages/plugin/vite/spec/fixtures/vite-configs/vite.renderer.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default {}; 3 | -------------------------------------------------------------------------------- /packages/plugin/vite/src/Config.ts: -------------------------------------------------------------------------------- 1 | import type { LibraryOptions } from 'vite'; 2 | 3 | export interface VitePluginBuildConfig { 4 | /** 5 | * Alias of `build.lib.entry` in `config`. 6 | */ 7 | entry: LibraryOptions['entry']; 8 | /** 9 | * Vite config file path. 10 | */ 11 | config: string; 12 | /** 13 | * The build target is main process or preload script. 14 | * @defaultValue 'main' 15 | */ 16 | target?: 'main' | 'preload'; 17 | } 18 | 19 | export interface VitePluginRendererConfig { 20 | /** 21 | * Human friendly name of your entry point. 22 | */ 23 | name: string; 24 | /** 25 | * Vite config file path. 26 | */ 27 | config: string; 28 | } 29 | 30 | export interface VitePluginConfig { 31 | // Reserved option, may support modification in the future. 32 | // @defaultValue '.vite' 33 | // baseDir?: string; 34 | 35 | /** 36 | * Build anything such as Main process, Preload scripts and Worker process, etc. 37 | */ 38 | build: VitePluginBuildConfig[]; 39 | /** 40 | * Renderer process Vite configs. 41 | */ 42 | renderer: VitePluginRendererConfig[]; 43 | } 44 | -------------------------------------------------------------------------------- /packages/plugin/vite/src/config/vite.main.config.ts: -------------------------------------------------------------------------------- 1 | import { type ConfigEnv, mergeConfig, type UserConfig } from 'vite'; 2 | 3 | import { external, getBuildConfig, getBuildDefine, pluginHotRestart } from './vite.base.config'; 4 | 5 | export function getConfig(forgeEnv: ConfigEnv<'build'>, userConfig: UserConfig = {}): UserConfig { 6 | const { forgeConfigSelf } = forgeEnv; 7 | const define = getBuildDefine(forgeEnv); 8 | const config: UserConfig = { 9 | build: { 10 | rollupOptions: { 11 | external, 12 | }, 13 | }, 14 | plugins: [pluginHotRestart('restart')], 15 | define, 16 | resolve: { 17 | // Load the Node.js entry. 18 | conditions: ['node'], 19 | mainFields: ['module', 'jsnext:main', 'jsnext'], 20 | }, 21 | }; 22 | const buildConfig = getBuildConfig(forgeEnv); 23 | 24 | if (userConfig.build?.lib == null) { 25 | config.build!.lib = { 26 | entry: forgeConfigSelf.entry, 27 | fileName: () => '[name].js', 28 | formats: ['cjs'], 29 | }; 30 | } 31 | 32 | return mergeConfig(mergeConfig(buildConfig, config), userConfig); 33 | } 34 | -------------------------------------------------------------------------------- /packages/plugin/vite/src/config/vite.preload.config.ts: -------------------------------------------------------------------------------- 1 | import { type ConfigEnv, mergeConfig, type UserConfig } from 'vite'; 2 | 3 | import { external, getBuildConfig, pluginHotRestart } from './vite.base.config'; 4 | 5 | export function getConfig(forgeEnv: ConfigEnv<'build'>, userConfig: UserConfig = {}): UserConfig { 6 | const { forgeConfigSelf } = forgeEnv; 7 | const config: UserConfig = { 8 | build: { 9 | rollupOptions: { 10 | external, 11 | // Preload scripts may contain Web assets, so use the `build.rollupOptions.input` instead `build.lib.entry`. 12 | input: forgeConfigSelf.entry, 13 | output: { 14 | format: 'cjs', 15 | // It should not be split chunks. 16 | inlineDynamicImports: true, 17 | entryFileNames: '[name].js', 18 | chunkFileNames: '[name].js', 19 | assetFileNames: '[name].[ext]', 20 | }, 21 | }, 22 | }, 23 | plugins: [pluginHotRestart('reload')], 24 | }; 25 | const buildConfig = getBuildConfig(forgeEnv); 26 | 27 | return mergeConfig(mergeConfig(buildConfig, config), userConfig); 28 | } 29 | -------------------------------------------------------------------------------- /packages/plugin/vite/src/config/vite.renderer.config.ts: -------------------------------------------------------------------------------- 1 | import { type ConfigEnv, mergeConfig, type UserConfig } from 'vite'; 2 | 3 | import { pluginExposeRenderer } from './vite.base.config'; 4 | 5 | // https://vitejs.dev/config 6 | export function getConfig(forgeEnv: ConfigEnv<'renderer'>, userConfig: UserConfig = {}) { 7 | const { root, mode, forgeConfigSelf } = forgeEnv; 8 | const name = forgeConfigSelf.name ?? ''; 9 | 10 | const config: UserConfig = { 11 | root, 12 | mode, 13 | base: './', 14 | build: { 15 | outDir: `.vite/renderer/${name}`, 16 | }, 17 | plugins: [pluginExposeRenderer(name)], 18 | resolve: { 19 | preserveSymlinks: true, 20 | }, 21 | clearScreen: false, 22 | }; 23 | 24 | return mergeConfig(config, userConfig); 25 | } 26 | -------------------------------------------------------------------------------- /packages/plugin/vite/src/util/plugins.ts: -------------------------------------------------------------------------------- 1 | import type { Plugin } from 'vite'; 2 | 3 | export function onBuildDone(callback: () => void) { 4 | return { 5 | name: '@electron-forge/plugin-vite:build-done', 6 | closeBundle() { 7 | callback(); 8 | }, 9 | } as Plugin; 10 | } 11 | -------------------------------------------------------------------------------- /packages/plugin/vite/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | // Fix build types check error. 2 | declare module 'rollup/parseAst'; 3 | -------------------------------------------------------------------------------- /packages/plugin/webpack/README.md: -------------------------------------------------------------------------------- 1 | ## plugin-webpack 2 | 3 | This plugin makes it easy to set up standard webpack tooling to compile both your main process code and your renderer process code, with built-in support for Hot Module Replacement (HMR) in the renderer process and support for multiple renderers. 4 | 5 | ```javascript 6 | // forge.config.js 7 | 8 | module.exports = { 9 | plugins: [ 10 | { 11 | name: '@electron-forge/plugin-webpack', 12 | config: { 13 | mainConfig: './webpack.main.config.js', 14 | renderer: { 15 | config: './webpack.renderer.config.js', 16 | entryPoints: [{ 17 | name: 'main_window', 18 | html: './src/renderer/index.html', 19 | js: './src/renderer/index.js', 20 | preload: { 21 | js: './src/preload.js' 22 | } 23 | }] 24 | } 25 | } 26 | } 27 | ] 28 | }; 29 | ``` 30 | -------------------------------------------------------------------------------- /packages/plugin/webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/plugin-webpack", 3 | "version": "7.8.1", 4 | "description": "Webpack plugin for Electron Forge, lets you use Webpack directly in your tooling", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/WebpackPlugin.js", 9 | "typings": "dist/WebpackPlugin.d.ts", 10 | "devDependencies": { 11 | "@electron/packager": "^18.3.5", 12 | "@malept/cross-spawn-promise": "^2.0.0", 13 | "@types/node": "^18.0.3", 14 | "vitest": "^3.1.3", 15 | "which": "^2.0.2", 16 | "xvfb-maybe": "^0.2.1" 17 | }, 18 | "engines": { 19 | "node": ">= 16.4.0" 20 | }, 21 | "dependencies": { 22 | "@electron-forge/core-utils": "7.8.1", 23 | "@electron-forge/plugin-base": "7.8.1", 24 | "@electron-forge/shared-types": "7.8.1", 25 | "@electron-forge/web-multi-logger": "7.8.1", 26 | "chalk": "^4.0.0", 27 | "debug": "^4.3.1", 28 | "fast-glob": "^3.2.7", 29 | "fs-extra": "^10.0.0", 30 | "html-webpack-plugin": "^5.5.3", 31 | "listr2": "^7.0.2", 32 | "webpack": "^5.69.1", 33 | "webpack-dev-server": "^4.0.0", 34 | "webpack-merge": "^5.7.3" 35 | }, 36 | "publishConfig": { 37 | "access": "public" 38 | }, 39 | "files": [ 40 | "dist", 41 | "src" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /packages/plugin/webpack/spec/fixtures/apps/native-modules/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "native-app", 3 | "version": "1.0.0", 4 | "main": "./.webpack/main/index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "start": "npx electron ." 8 | }, 9 | "devDependencies": { 10 | "@vercel/webpack-asset-relocator-loader": "1.7.3", 11 | "electron": "^33.3.1" 12 | }, 13 | "dependencies": { 14 | "native-hello-world": "^2.0.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/plugin/webpack/spec/fixtures/apps/native-modules/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/plugin/webpack/spec/fixtures/apps/native-modules/src/index.js: -------------------------------------------------------------------------------- 1 | import { app, BrowserWindow, ipcMain } from 'electron'; 2 | 3 | let count = 0; 4 | ipcMain.on('stdout', (_, line) => { 5 | console.log(line); 6 | count += 1; 7 | 8 | if (count > 1) { 9 | process.exit(); 10 | } 11 | }); 12 | 13 | app.on('ready', () => { 14 | const mainWindow = new BrowserWindow({ 15 | height: 600, 16 | width: 800, 17 | show: false, 18 | webPreferences: { 19 | nodeIntegration: true, 20 | contextIsolation: false, 21 | preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY, 22 | }, 23 | }); 24 | 25 | mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY); 26 | }); 27 | 28 | const helloWorld = require('native-hello-world'); 29 | console.log(`${helloWorld()} from the main`); 30 | 31 | setTimeout(() => { 32 | process.exit(); 33 | }, 10000); 34 | -------------------------------------------------------------------------------- /packages/plugin/webpack/spec/fixtures/apps/native-modules/src/preload.js: -------------------------------------------------------------------------------- 1 | import { ipcRenderer } from 'electron'; 2 | 3 | const helloWorld = require('native-hello-world'); 4 | ipcRenderer.send('stdout', `${helloWorld()} from the preload`); 5 | -------------------------------------------------------------------------------- /packages/plugin/webpack/spec/fixtures/apps/native-modules/src/renderer.js: -------------------------------------------------------------------------------- 1 | import { ipcRenderer } from 'electron'; 2 | 3 | const helloWorld = require('native-hello-world'); 4 | ipcRenderer.send('stdout', `${helloWorld()} from the renderer`); 5 | -------------------------------------------------------------------------------- /packages/plugin/webpack/spec/fixtures/apps/native-modules/webpack.main.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | context: __dirname, 3 | entry: './src/index.js', 4 | performance: { 5 | hints: false, 6 | }, 7 | module: { 8 | rules: require('./webpack.rules'), 9 | }, 10 | resolve: { 11 | extensions: ['.js'], 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /packages/plugin/webpack/spec/fixtures/apps/native-modules/webpack.renderer.config.js: -------------------------------------------------------------------------------- 1 | const rules = require('./webpack.rules'); 2 | 3 | module.exports = { 4 | context: __dirname, 5 | target: 'electron-renderer', 6 | performance: { 7 | hints: false, 8 | }, 9 | module: { 10 | rules, 11 | }, 12 | resolve: { 13 | extensions: ['.js'], 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /packages/plugin/webpack/spec/fixtures/apps/native-modules/webpack.rules.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | // Add support for native node modules 3 | { 4 | // We're specifying native_modules in the test because the asset relocator loader generates a 5 | // "fake" .node file which is really a cjs file. 6 | test: /native_modules[/\\].+\.node$/, 7 | use: 'node-loader', 8 | }, 9 | { 10 | test: /[/\\]node_modules[/\\].+\.(m?js|node)$/, 11 | parser: { amd: false }, 12 | use: { 13 | loader: '@vercel/webpack-asset-relocator-loader', 14 | options: { 15 | outputAssetBase: 'native_modules', 16 | }, 17 | }, 18 | }, 19 | ]; 20 | -------------------------------------------------------------------------------- /packages/plugin/webpack/spec/fixtures/main_config_external/mainConfig.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: './foo/main.js', 3 | }; 4 | -------------------------------------------------------------------------------- /packages/plugin/webpack/spec/fixtures/main_config_external/mainConfig.module.js: -------------------------------------------------------------------------------- 1 | module.exports.default = { 2 | entry: './foo/main.js', 3 | }; 4 | -------------------------------------------------------------------------------- /packages/plugin/webpack/spec/util/once.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it, vi } from 'vitest'; 2 | 3 | import once from '../../src/util/once'; 4 | 5 | describe('Once', () => { 6 | it('triggers wrapped function', () => { 7 | const fakeA = vi.fn(); 8 | const fakeB = vi.fn(); 9 | const [wrappedA] = once(fakeA, fakeB); 10 | wrappedA(); 11 | expect(fakeA).toHaveBeenCalled(); 12 | expect(fakeB).not.toHaveBeenCalled(); 13 | }); 14 | 15 | it('triggers only once', () => { 16 | const fakeA = vi.fn(); 17 | const fakeB = vi.fn(); 18 | const [wrappedA, wrappedB] = once(fakeA, fakeB); 19 | wrappedA(); 20 | wrappedB(); 21 | expect(fakeA).toHaveBeenCalled(); 22 | expect(fakeB).not.toHaveBeenCalled(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/plugin/webpack/src/util/ElectronForgeLogging.ts: -------------------------------------------------------------------------------- 1 | import { Tab } from '@electron-forge/web-multi-logger'; 2 | import { Compiler } from 'webpack'; 3 | 4 | const pluginName = 'ElectronForgeLogging'; 5 | 6 | export default class LoggingPlugin { 7 | tab: Tab; 8 | 9 | constructor(tab: Tab) { 10 | this.tab = tab; 11 | } 12 | 13 | apply(compiler: Compiler): void { 14 | compiler.hooks.done.tap(pluginName, (stats) => { 15 | if (stats) { 16 | this.tab.log( 17 | stats.toString({ 18 | colors: true, 19 | }) 20 | ); 21 | } 22 | }); 23 | compiler.hooks.failed.tap(pluginName, (err) => this.tab.log(err.message)); 24 | compiler.hooks.infrastructureLog.tap(pluginName, (name, _type, args) => { 25 | this.tab.log(`${name} - ${args?.join(' ')}\n`); 26 | return true; 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/plugin/webpack/src/util/EntryPointPreloadPlugin.ts: -------------------------------------------------------------------------------- 1 | import { PluginBase } from '@electron-forge/plugin-base'; 2 | 3 | import { EntryPointPluginConfig } from '../Config'; 4 | 5 | export default class EntryPointPreloadPlugin extends PluginBase { 6 | name = this.config.name; 7 | apply() { 8 | // noop 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/plugin/webpack/src/util/once.ts: -------------------------------------------------------------------------------- 1 | /* eslint "arrow-parens": "off", "@typescript-eslint/no-explicit-any": "off" */ 2 | export default (fn1: A, fn2: B): [A, B] => { 3 | let once = true; 4 | let val: any; 5 | const make = (fn: T): T => 6 | ((...args: any[]) => { 7 | if (once) { 8 | val = (fn as any)(...args); 9 | once = false; 10 | } 11 | return val; 12 | }) as unknown as T; 13 | return [make(fn1), make(fn2)]; 14 | }; 15 | -------------------------------------------------------------------------------- /packages/plugin/webpack/src/util/processConfig.ts: -------------------------------------------------------------------------------- 1 | import { Configuration } from 'webpack'; 2 | 3 | import { ConfigurationFactory } from '../WebpackConfig'; 4 | 5 | const trivialConfigurationFactory = 6 | (config: Configuration): ConfigurationFactory => 7 | () => 8 | config; 9 | 10 | export type ConfigProcessor = (config: ConfigurationFactory) => Promise; 11 | 12 | // Ensure processing logic is run for both `Configuration` and 13 | // `ConfigurationFactory` config variants. 14 | const processConfig = async (processor: ConfigProcessor, config: Configuration | ConfigurationFactory): Promise => { 15 | const configFactory = typeof config === 'function' ? config : trivialConfigurationFactory(config); 16 | return processor(configFactory); 17 | }; 18 | 19 | export default processConfig; 20 | -------------------------------------------------------------------------------- /packages/publisher/base-static/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/publisher-static", 3 | "version": "7.8.1", 4 | "description": "Base publisher for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/PublisherStatic.js", 9 | "typings": "dist/PublisherStatic.d.ts", 10 | "dependencies": { 11 | "@electron-forge/publisher-base": "7.8.1", 12 | "@electron-forge/shared-types": "7.8.1" 13 | }, 14 | "devDependencies": { 15 | "vitest": "^3.1.3" 16 | }, 17 | "engines": { 18 | "node": ">= 16.4.0" 19 | }, 20 | "publishConfig": { 21 | "access": "public" 22 | }, 23 | "files": [ 24 | "dist", 25 | "src" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/publisher/base-static/spec/StaticPublisher.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | 3 | import { PublisherStatic, StaticPublisherConfig } from '../src/PublisherStatic'; 4 | 5 | class PublisherImpl extends PublisherStatic { 6 | defaultPlatforms = []; 7 | 8 | name = 'test'; 9 | 10 | public exposedKeyForArtifact = this.keyForArtifact; 11 | } 12 | 13 | describe('PublisherStatic', () => { 14 | describe('keyForArtifact', () => { 15 | it('should by default concat prefix, platform, arch and filename', () => { 16 | const publisher = new PublisherImpl({}); 17 | expect( 18 | publisher.exposedKeyForArtifact({ 19 | platform: 'plat', 20 | arch: 'arch', 21 | keyPrefix: 'stuff', 22 | path: __filename, 23 | }) 24 | ).toEqual('stuff/plat/arch/StaticPublisher.spec.ts'); 25 | }); 26 | 27 | it('should call the provided method', () => { 28 | const publisher = new PublisherImpl({ 29 | keyResolver: () => 'lololol', 30 | }); 31 | expect( 32 | publisher.exposedKeyForArtifact({ 33 | platform: 'plat', 34 | arch: 'arch', 35 | keyPrefix: 'stuff', 36 | path: __filename, 37 | }) 38 | ).toEqual('lololol'); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /packages/publisher/base-static/src/PublisherStatic.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { PublisherBase, PublisherOptions } from '@electron-forge/publisher-base'; 4 | import { ForgeArch, ForgePlatform } from '@electron-forge/shared-types'; 5 | 6 | interface StaticArtifact { 7 | path: string; 8 | platform: ForgePlatform; 9 | arch: ForgeArch; 10 | keyPrefix: string; 11 | } 12 | 13 | interface StaticPublisherConfig { 14 | /** 15 | * Custom function to provide the key to upload a given file to 16 | */ 17 | keyResolver?: (fileName: string, platform: string, arch: string) => string; 18 | } 19 | 20 | export default abstract class PublisherStatic extends PublisherBase { 21 | protected keyForArtifact(artifact: StaticArtifact): string { 22 | if (this.config.keyResolver) { 23 | return this.config.keyResolver(path.basename(artifact.path), artifact.platform, artifact.arch); 24 | } 25 | 26 | return `${artifact.keyPrefix}/${artifact.platform}/${artifact.arch}/${path.basename(artifact.path)}`; 27 | } 28 | } 29 | 30 | export { PublisherStatic, StaticPublisherConfig, PublisherOptions }; 31 | -------------------------------------------------------------------------------- /packages/publisher/base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/publisher-base", 3 | "version": "7.8.1", 4 | "description": "Base publisher for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/Publisher.js", 9 | "typings": "dist/Publisher.d.ts", 10 | "dependencies": { 11 | "@electron-forge/shared-types": "7.8.1" 12 | }, 13 | "devDependencies": { 14 | "vitest": "^3.1.3" 15 | }, 16 | "engines": { 17 | "node": ">= 16.4.0" 18 | }, 19 | "publishConfig": { 20 | "access": "public" 21 | }, 22 | "files": [ 23 | "dist", 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /packages/publisher/base/spec/Publisher.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | 3 | import Publisher, { PublisherOptions } from '../src/Publisher'; 4 | 5 | class PublisherImpl extends Publisher { 6 | defaultPlatforms = []; 7 | 8 | name = 'test'; 9 | } 10 | 11 | describe('Publisher', () => { 12 | it('should define __isElectronForgePublisher', () => { 13 | const publisher = new PublisherImpl(null); 14 | expect(publisher).toHaveProperty('__isElectronForgePublisher', true); 15 | }); 16 | 17 | it('__isElectronForgePublisher should not be settable', () => { 18 | const publisher = new PublisherImpl(null); 19 | expect(() => { 20 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 21 | (publisher as any).__isElectronForgePublisher = false; 22 | }).toThrow(); 23 | expect(() => { 24 | Object.defineProperty(publisher, '__isElectronForgePublisher', { 25 | value: false, 26 | }); 27 | }).toThrow(); 28 | expect(publisher).toHaveProperty('__isElectronForgePublisher', true); 29 | }); 30 | 31 | it('should throw an error when publish is called is called', async () => { 32 | const publisher = new PublisherImpl(null); 33 | await expect(publisher.publish({} as PublisherOptions)).rejects.toThrow(); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/publisher/bitbucket/README.md: -------------------------------------------------------------------------------- 1 | ## Electron Forge: publisher-bitbucket 2 | 3 | `@electron-forge/publisher-bitbucket` publishes your artifacts to Bitbucket where users will be able to download them. 4 | 5 | This publish target is for Bitbucket Cloud only and will not work with self hosted Bitbucket Server instances. 6 | 7 | Configuration options are documented in [`PublisherBitbucketConfig`](https://js.electronforge.io/interfaces/_electron_forge_publisher_bitbucket.PublisherBitbucketConfig.html). 8 | 9 | ```javascript title=forge.config.js 10 | module.exports = { 11 | // ... 12 | publishers: [ 13 | { 14 | name: '@electron-forge/publisher-bitbucket', 15 | config: { 16 | repository: { 17 | owner: 'myusername', 18 | name: 'myreponame' 19 | }, 20 | auth: { 21 | username: 'myusername', 22 | appPassword: 'mysecretapppassword' 23 | } 24 | } 25 | } 26 | ] 27 | }; 28 | ``` 29 | 30 | Alternatively you can (and should) use environment variables for the authentication 31 | 32 | ```sh 33 | # env.sh 34 | BITBUCKET_USERNAME="myusername" 35 | BITBUCKET_APP_PASSWORD="mysecretapppassword" 36 | ``` 37 | 38 | ```sh 39 | source env.sh 40 | ``` 41 | -------------------------------------------------------------------------------- /packages/publisher/bitbucket/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/publisher-bitbucket", 3 | "version": "7.8.1", 4 | "description": "Bitbucket publisher for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Luke Batchelor", 7 | "license": "MIT", 8 | "main": "dist/PublisherBitbucket.js", 9 | "typings": "dist/PublisherBitbucket.d.ts", 10 | "engines": { 11 | "node": ">= 16.4.0" 12 | }, 13 | "dependencies": { 14 | "@electron-forge/publisher-base": "7.8.1", 15 | "form-data": "^4.0.0", 16 | "fs-extra": "^10.0.0", 17 | "node-fetch": "^2.6.7" 18 | }, 19 | "publishConfig": { 20 | "access": "public" 21 | }, 22 | "files": [ 23 | "dist", 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /packages/publisher/bitbucket/src/Config.ts: -------------------------------------------------------------------------------- 1 | export interface BitbucketRepository { 2 | /** 3 | * The name of your repository 4 | */ 5 | name: string; 6 | /** 7 | * The owner of your repository, this is either your username or the name of 8 | * the organization that owns the repository. 9 | */ 10 | owner: string; 11 | } 12 | 13 | export interface BitbucketAuth { 14 | /** 15 | * The username to use when uploading. 16 | * 17 | * You can set the BITBUCKET_USERNAME environment variable if you don't want to hard 18 | * code this into your config. 19 | */ 20 | username?: string; 21 | /** 22 | * An authorization token with permission to upload downloads to this 23 | * repository. 24 | * 25 | * You can set the BITBUCKET_APP_PASSWORD environment variable if you don't want to hard 26 | * code this into your config. 27 | */ 28 | appPassword?: string; 29 | } 30 | 31 | export interface PublisherBitbucketConfig { 32 | /** 33 | * Details that identify your repository (name and owner) 34 | */ 35 | repository: BitbucketRepository; 36 | /** 37 | * User details for uploading releases 38 | */ 39 | auth: BitbucketAuth; 40 | /** 41 | * If true, will replace an existing files of the same name (will throw an error otherwise). 42 | */ 43 | replaceExistingFiles?: boolean; 44 | } 45 | -------------------------------------------------------------------------------- /packages/publisher/electron-release-server/README.md: -------------------------------------------------------------------------------- 1 | ## publisher-electron-release-server 2 | 3 | `@electron-forge/publisher-electron-release-server` publishes all your artifacts to a hosted instance of [Electron Release Server](https://github.com/ArekSredzki/electron-release-server) where users will be able to download them. 4 | 5 | Please note that Electron Release Server is a community powered project and is not associated with Electron Forge or the Electron project directly. 6 | 7 | Configuration options are documented in [`PublisherERSConfig`](https://js.electronforge.io/interfaces/_electron_forge_publisher_electron_release_server.PublisherERSConfig.html). 8 | 9 | ```javascript title=forge.config.js 10 | module.exports = { 11 | // ... 12 | publishers: [ 13 | { 14 | name: '@electron-forge/publisher-electron-release-server', 15 | config: { 16 | baseUrl: 'https://update.server.com', 17 | username: 'admin', 18 | password: 'admin' 19 | } 20 | } 21 | ] 22 | }; 23 | ``` 24 | -------------------------------------------------------------------------------- /packages/publisher/electron-release-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/publisher-electron-release-server", 3 | "version": "7.8.1", 4 | "description": "Electron release server publisher for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/PublisherERS.js", 9 | "typings": "dist/PublisherERS.d.ts", 10 | "devDependencies": { 11 | "msw": "^2.7.0", 12 | "vitest": "^3.1.3" 13 | }, 14 | "engines": { 15 | "node": ">= 16.4.0" 16 | }, 17 | "dependencies": { 18 | "@electron-forge/publisher-base": "7.8.1", 19 | "@electron-forge/shared-types": "7.8.1", 20 | "debug": "^4.3.1", 21 | "form-data": "^4.0.0", 22 | "fs-extra": "^10.0.0", 23 | "node-fetch": "^2.6.7" 24 | }, 25 | "publishConfig": { 26 | "access": "public" 27 | }, 28 | "files": [ 29 | "dist", 30 | "src" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /packages/publisher/electron-release-server/src/Config.ts: -------------------------------------------------------------------------------- 1 | export interface PublisherERSConfig { 2 | /** 3 | * The base URL of your instance of ERS. 4 | * 5 | * E.g. https://my-update.server.com 6 | */ 7 | baseUrl: string; 8 | /** 9 | * The username you use to sign in to ERS 10 | */ 11 | username: string; 12 | /** 13 | * The password you use to sign in to ERS 14 | */ 15 | password: string; 16 | /** 17 | * The release channel you want to send artifacts to, normally something like 18 | * "stable", "beta" or "alpha". 19 | * 20 | * If left unspecified we will try to infer the channel from your version 21 | * field in your package.json. 22 | * 23 | * Default: stable 24 | */ 25 | channel?: string; 26 | 27 | /** 28 | * The "flavor" of the binary that you want to release to. 29 | * This is useful if you want to provide multiple versions 30 | * of the same application version (e.g. full and lite) 31 | * to end users. 32 | */ 33 | flavor?: string; 34 | } 35 | -------------------------------------------------------------------------------- /packages/publisher/gcs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/publisher-gcs", 3 | "version": "7.8.1", 4 | "description": "Google Cloud Storage publisher for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Evgeny Vlasenko", 7 | "license": "MIT", 8 | "main": "dist/PublisherGCS.js", 9 | "typings": "dist/PublisherGCS.d.ts", 10 | "engines": { 11 | "node": ">= 16.4.0" 12 | }, 13 | "dependencies": { 14 | "@electron-forge/publisher-static": "7.8.1", 15 | "@electron-forge/shared-types": "7.8.1", 16 | "@google-cloud/storage": "^7.5.0", 17 | "debug": "^4.3.1" 18 | }, 19 | "publishConfig": { 20 | "access": "public" 21 | }, 22 | "files": [ 23 | "dist", 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /packages/publisher/github/README.md: -------------------------------------------------------------------------------- 1 | ## publisher-github 2 | 3 | `@electron-forge/publisher-github` publishes all your artifacts to GitHub releases, this allows your users to download the files straight from your repository or if your repository is open source you can use [update.electronjs.org](https://github.com/electron/update.electronjs.org) and get a free hosted update service. 4 | 5 | Configuration options are documented in [`PublisherGithubConfig`](https://js.electronforge.io/interfaces/_electron_forge_publisher_github.PublisherGitHubConfig.html). 6 | 7 | ```javascript title=forge.config.js 8 | module.exports = { 9 | // ... 10 | publishers: [ 11 | { 12 | name: '@electron-forge/publisher-github', 13 | config: { 14 | repository: { 15 | owner: 'me', 16 | name: 'awesome-thing' 17 | }, 18 | prerelease: true 19 | } 20 | } 21 | ] 22 | }; 23 | ``` 24 | -------------------------------------------------------------------------------- /packages/publisher/github/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/publisher-github", 3 | "version": "7.8.1", 4 | "description": "Github publisher for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/PublisherGithub.js", 9 | "typings": "dist/PublisherGithub.d.ts", 10 | "devDependencies": { 11 | "vitest": "^3.1.3" 12 | }, 13 | "engines": { 14 | "node": ">= 16.4.0" 15 | }, 16 | "dependencies": { 17 | "@electron-forge/publisher-base": "7.8.1", 18 | "@electron-forge/shared-types": "7.8.1", 19 | "@octokit/core": "^5.2.1", 20 | "@octokit/plugin-retry": "^6.1.0", 21 | "@octokit/request-error": "^5.1.1", 22 | "@octokit/rest": "^20.1.2", 23 | "@octokit/types": "^6.1.2", 24 | "chalk": "^4.0.0", 25 | "debug": "^4.3.1", 26 | "fs-extra": "^10.0.0", 27 | "log-symbols": "^4.0.0", 28 | "mime-types": "^2.1.25" 29 | }, 30 | "publishConfig": { 31 | "access": "public" 32 | }, 33 | "files": [ 34 | "dist", 35 | "src" 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /packages/publisher/github/src/util/no-release-error.ts: -------------------------------------------------------------------------------- 1 | class NoReleaseError extends Error { 2 | code: number; 3 | 4 | constructor(code: number) { 5 | super('No GitHub Release found'); 6 | this.code = code; 7 | } 8 | } 9 | 10 | export { NoReleaseError as default }; 11 | -------------------------------------------------------------------------------- /packages/publisher/nucleus/README.md: -------------------------------------------------------------------------------- 1 | ## publisher-nucleus 2 | 3 | `@electron-forge/publisher-nucleus` publishes all your artifacts to an instance of Nucleus Update Server where users will be able to download them. This update service supports all three platforms. 4 | 5 | Check out the README at [`atlassian/nucleus`](https://github.com/atlassian/nucleus) for more information on this project. 6 | 7 | Configuration options are documented in [`Publisher 8 | NucleusConfig](https://js.electronforge.io/interfaces/_electron_forge_publisher_nucleus.PublisherNucleusConfig.html). 9 | 10 | ```javascript title=forge.config.js 11 | module.exports = { 12 | // ... 13 | publishers: [ 14 | { 15 | name: '@electron-forge/publisher-nucleus', 16 | config: { 17 | host: 'https://my-nucleus.mysite.com', 18 | appId: 1, 19 | channelId: 'abcdefg', 20 | token: 'my-token' 21 | } 22 | } 23 | ] 24 | }; 25 | ``` 26 | 27 | We recommend you set the `token`option using an environment variable, don't hard code into in your config. 28 | -------------------------------------------------------------------------------- /packages/publisher/nucleus/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/publisher-nucleus", 3 | "version": "7.8.1", 4 | "description": "Nucleus publisher for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/PublisherNucleus.js", 9 | "typings": "dist/PublisherNucleus.d.ts", 10 | "engines": { 11 | "node": ">= 16.4.0" 12 | }, 13 | "dependencies": { 14 | "@electron-forge/publisher-base": "7.8.1", 15 | "@electron-forge/shared-types": "7.8.1", 16 | "debug": "^4.3.1", 17 | "form-data": "^4.0.0", 18 | "node-fetch": "^2.6.7" 19 | }, 20 | "publishConfig": { 21 | "access": "public" 22 | }, 23 | "files": [ 24 | "dist", 25 | "src" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/publisher/nucleus/src/Config.ts: -------------------------------------------------------------------------------- 1 | export interface PublisherNucleusConfig { 2 | /** 3 | * Hostname (with https?://) of your instance of Nucleus 4 | */ 5 | host: string; 6 | /** 7 | * App ID of your target application in Nucleus 8 | */ 9 | appId: number; 10 | /** 11 | * Channel ID of your target application in Nucleus 12 | */ 13 | channelId: string; 14 | /** 15 | * Authentication token for your app, you can find this on the Nucleus web UI 16 | */ 17 | token: string; 18 | } 19 | -------------------------------------------------------------------------------- /packages/publisher/s3/README.md: -------------------------------------------------------------------------------- 1 | ## publisher-s3 2 | 3 | `@electron-forge/publisher-s3` publishes all your artifacts to an Amazon S3 bucket where users will be able to download them. 4 | 5 | By default, all files are positioned at the following key: 6 | 7 | ${config.folder || appVersion}/${artifactName} 8 | 9 | Configuration options are documented in [PublisherS3Config](https://js.electronforge.io/interfaces/_electron_forge_publisher_s3.PublisherS3Config.html). 10 | 11 | ```javascript title=forge.config.js 12 | module.exports = { 13 | // ... 14 | publishers: [ 15 | { 16 | name: '@electron-forge/publisher-s3', 17 | config: { 18 | bucket: 'my-bucket', 19 | public: true 20 | } 21 | } 22 | ] 23 | }; 24 | ``` 25 | 26 | If you run publish twice with the same version on the same platform, it is possible for your old artifacts to get overwritten in S3. It is your responsibility to ensure that you don't overwrite your own releases. 27 | 28 | ### Authentication 29 | 30 | It is recommended to follow the [Amazon AWS guide](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html) and set either a shared credentials guide or the proper environment variables. However, if that is not possible, the publisher config allows the setting of the accessKeyId and secretAccessKey configuration options. 31 | -------------------------------------------------------------------------------- /packages/publisher/s3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/publisher-s3", 3 | "version": "7.8.1", 4 | "description": "S3 publisher for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/PublisherS3.js", 9 | "typings": "dist/PublisherS3.d.ts", 10 | "engines": { 11 | "node": ">= 16.4.0" 12 | }, 13 | "dependencies": { 14 | "@aws-sdk/client-s3": "^3.654.0", 15 | "@aws-sdk/lib-storage": "^3.654.0", 16 | "@aws-sdk/types": "^3.654.0", 17 | "@electron-forge/publisher-static": "7.8.1", 18 | "@electron-forge/shared-types": "7.8.1", 19 | "debug": "^4.3.1" 20 | }, 21 | "publishConfig": { 22 | "access": "public" 23 | }, 24 | "files": [ 25 | "dist", 26 | "src" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /packages/publisher/snapcraft/README.md: -------------------------------------------------------------------------------- 1 | ## publisher-snapcraft 2 | 3 | The Snapcraft target publishes your .snap artifacts to the Snap Store. All configuration of your package is done via the Snapcraft maker. 4 | 5 | This target requires that the system has the snapcraft utility installed. 6 | 7 | Configuration options are documented in [PublisherSnapConfig](https://js.electronforge.io/interfaces/_electron_forge_publisher_snapcraft.PublisherSnapcraftConfig.html). 8 | 9 | ```javascript title=forge.config.js 10 | module.exports = { 11 | // ... 12 | publishers: [ 13 | { 14 | name: '@electron-forge/publisher-snapcraft', 15 | config: { 16 | release: 'latest/edge, insider/stable' 17 | } 18 | } 19 | ] 20 | }; 21 | ``` 22 | -------------------------------------------------------------------------------- /packages/publisher/snapcraft/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/publisher-snapcraft", 3 | "version": "7.8.1", 4 | "description": "Snapcraft publisher for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/PublisherSnapcraft.js", 9 | "typings": "dist/PublisherSnapcraft.d.ts", 10 | "engines": { 11 | "node": ">= 16.4.0" 12 | }, 13 | "dependencies": { 14 | "@electron-forge/publisher-base": "7.8.1", 15 | "fs-extra": "^10.0.0" 16 | }, 17 | "optionalDependencies": { 18 | "electron-installer-snap": "^5.2.0" 19 | }, 20 | "publishConfig": { 21 | "access": "public" 22 | }, 23 | "files": [ 24 | "dist", 25 | "src" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/publisher/snapcraft/src/Config.ts: -------------------------------------------------------------------------------- 1 | export interface PublisherSnapcraftConfig { 2 | /** 3 | * A comma-separated list of channels to release to 4 | */ 5 | release: string; 6 | } 7 | -------------------------------------------------------------------------------- /packages/template/base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/template-base", 3 | "version": "7.8.1", 4 | "description": "Base template for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/BaseTemplate.js", 9 | "typings": "dist/BaseTemplate.d.ts", 10 | "engines": { 11 | "node": ">= 16.4.0" 12 | }, 13 | "dependencies": { 14 | "@electron-forge/core-utils": "7.8.1", 15 | "@electron-forge/shared-types": "7.8.1", 16 | "@malept/cross-spawn-promise": "^2.0.0", 17 | "debug": "^4.3.1", 18 | "fs-extra": "^10.0.0", 19 | "username": "^5.1.0" 20 | }, 21 | "devDependencies": { 22 | "@electron-forge/test-utils": "7.8.1", 23 | "vitest": "^3.1.3" 24 | }, 25 | "publishConfig": { 26 | "access": "public" 27 | }, 28 | "files": [ 29 | "dist", 30 | "src", 31 | "tmpl" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /packages/template/base/src/determine-author.ts: -------------------------------------------------------------------------------- 1 | import { PackagePerson } from '@electron-forge/shared-types'; 2 | import { spawn } from '@malept/cross-spawn-promise'; 3 | import debug from 'debug'; 4 | import username from 'username'; 5 | 6 | const d = debug('electron-forge:determine-author'); 7 | 8 | async function getGitConfig(name: string, cwd: string): Promise { 9 | const value = await spawn('git', ['config', '--get', name], { cwd }); 10 | return value.trim(); 11 | } 12 | 13 | const getAuthorFromGitConfig = async (dir: string): Promise => { 14 | try { 15 | const name = await getGitConfig('user.name', dir); 16 | const email = await getGitConfig('user.email', dir); 17 | return { name, email }; 18 | } catch (err) { 19 | d('Error when getting git config:', err); 20 | return undefined; 21 | } 22 | }; 23 | 24 | export default async (dir: string): Promise => (await getAuthorFromGitConfig(dir)) || username(); 25 | -------------------------------------------------------------------------------- /packages/template/base/tmpl/_npmrc: -------------------------------------------------------------------------------- 1 | node-linker = hoisted 2 | -------------------------------------------------------------------------------- /packages/template/base/tmpl/forge.config.js: -------------------------------------------------------------------------------- 1 | const { FusesPlugin } = require('@electron-forge/plugin-fuses'); 2 | const { FuseV1Options, FuseVersion } = require('@electron/fuses'); 3 | 4 | module.exports = { 5 | packagerConfig: { 6 | asar: true, 7 | }, 8 | rebuildConfig: {}, 9 | makers: [ 10 | { 11 | name: '@electron-forge/maker-squirrel', 12 | config: {}, 13 | }, 14 | { 15 | name: '@electron-forge/maker-zip', 16 | platforms: ['darwin'], 17 | }, 18 | { 19 | name: '@electron-forge/maker-deb', 20 | config: {}, 21 | }, 22 | { 23 | name: '@electron-forge/maker-rpm', 24 | config: {}, 25 | }, 26 | ], 27 | plugins: [ 28 | { 29 | name: '@electron-forge/plugin-auto-unpack-natives', 30 | config: {}, 31 | }, 32 | // Fuses are used to enable/disable various Electron functionality 33 | // at package time, before code signing the application 34 | new FusesPlugin({ 35 | version: FuseVersion.V1, 36 | [FuseV1Options.RunAsNode]: false, 37 | [FuseV1Options.EnableCookieEncryption]: true, 38 | [FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false, 39 | [FuseV1Options.EnableNodeCliInspectArguments]: false, 40 | [FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true, 41 | [FuseV1Options.OnlyLoadAppFromAsar]: true, 42 | }), 43 | ], 44 | }; 45 | -------------------------------------------------------------------------------- /packages/template/base/tmpl/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, 3 | Arial, sans-serif; 4 | margin: auto; 5 | max-width: 38rem; 6 | padding: 2rem; 7 | } 8 | -------------------------------------------------------------------------------- /packages/template/base/tmpl/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hello World! 6 | 7 | 8 | 9 |

💖 Hello World!

10 |

Welcome to your Electron application.

11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/template/base/tmpl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "productName": "", 4 | "version": "1.0.0", 5 | "description": "My Electron application description", 6 | "main": "src/index.js", 7 | "scripts": { 8 | "start": "electron-forge start", 9 | "package": "electron-forge package", 10 | "make": "electron-forge make", 11 | "publish": "electron-forge publish" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /packages/template/base/tmpl/preload.js: -------------------------------------------------------------------------------- 1 | // See the Electron documentation for details on how to use preload scripts: 2 | // https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts 3 | -------------------------------------------------------------------------------- /packages/template/vite-typescript/.eslintignore: -------------------------------------------------------------------------------- 1 | tmpl 2 | -------------------------------------------------------------------------------- /packages/template/vite-typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/template-vite-typescript", 3 | "version": "7.8.1", 4 | "description": "Vite-TypeScript template for Electron Forge, gets you started with Vite really quickly", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/electron/forge", 8 | "directory": "packages/template/vite-typescript" 9 | }, 10 | "author": "caoxiemeihao", 11 | "license": "MIT", 12 | "main": "dist/ViteTypeScriptTemplate.js", 13 | "typings": "dist/ViteTypeScriptTemplate.d.ts", 14 | "engines": { 15 | "node": ">= 16.4.0" 16 | }, 17 | "dependencies": { 18 | "@electron-forge/shared-types": "7.8.1", 19 | "@electron-forge/template-base": "7.8.1", 20 | "fs-extra": "^10.0.0" 21 | }, 22 | "devDependencies": { 23 | "@electron-forge/core-utils": "7.8.1", 24 | "@electron-forge/test-utils": "7.8.1", 25 | "fast-glob": "^3.2.7", 26 | "vitest": "^3.1.3" 27 | }, 28 | "files": [ 29 | "dist", 30 | "src", 31 | "tmpl" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /packages/template/vite-typescript/tmpl/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "node": true 6 | }, 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/eslint-recommended", 10 | "plugin:@typescript-eslint/recommended", 11 | "plugin:import/recommended", 12 | "plugin:import/electron", 13 | "plugin:import/typescript" 14 | ], 15 | "parser": "@typescript-eslint/parser" 16 | } 17 | -------------------------------------------------------------------------------- /packages/template/vite-typescript/tmpl/forge.env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/template/vite-typescript/tmpl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "@electron-forge/plugin-vite": "ELECTRON_FORGE/VERSION", 4 | "@typescript-eslint/eslint-plugin": "^5.0.0", 5 | "@typescript-eslint/parser": "^5.0.0", 6 | "eslint": "^8.0.1", 7 | "eslint-plugin-import": "^2.25.0", 8 | "ts-node": "^10.0.0", 9 | "typescript": "~4.5.4", 10 | "vite": "^5.0.12" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/template/vite-typescript/tmpl/preload.ts: -------------------------------------------------------------------------------- 1 | // See the Electron documentation for details on how to use preload scripts: 2 | // https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts 3 | -------------------------------------------------------------------------------- /packages/template/vite-typescript/tmpl/renderer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file will automatically be loaded by vite and run in the "renderer" context. 3 | * To learn more about the differences between the "main" and the "renderer" context in 4 | * Electron, visit: 5 | * 6 | * https://electronjs.org/docs/tutorial/process-model 7 | * 8 | * By default, Node.js integration in this file is disabled. When enabling Node.js integration 9 | * in a renderer process, please be aware of potential security implications. You can read 10 | * more about security risks here: 11 | * 12 | * https://electronjs.org/docs/tutorial/security 13 | * 14 | * To enable Node.js integration in this file, open up `main.ts` and enable the `nodeIntegration` 15 | * flag: 16 | * 17 | * ``` 18 | * // Create the browser window. 19 | * mainWindow = new BrowserWindow({ 20 | * width: 800, 21 | * height: 600, 22 | * webPreferences: { 23 | * nodeIntegration: true 24 | * } 25 | * }); 26 | * ``` 27 | */ 28 | 29 | import './index.css'; 30 | 31 | console.log('👋 This message is being logged by "renderer.ts", included via Vite'); 32 | -------------------------------------------------------------------------------- /packages/template/vite-typescript/tmpl/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "commonjs", 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "noImplicitAny": true, 9 | "sourceMap": true, 10 | "baseUrl": ".", 11 | "outDir": "dist", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/template/vite-typescript/tmpl/vite.main.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | // https://vitejs.dev/config 4 | export default defineConfig({}); 5 | -------------------------------------------------------------------------------- /packages/template/vite-typescript/tmpl/vite.preload.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | // https://vitejs.dev/config 4 | export default defineConfig({}); 5 | -------------------------------------------------------------------------------- /packages/template/vite-typescript/tmpl/vite.renderer.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | // https://vitejs.dev/config 4 | export default defineConfig({}); 5 | -------------------------------------------------------------------------------- /packages/template/vite/.eslintignore: -------------------------------------------------------------------------------- 1 | tmpl 2 | -------------------------------------------------------------------------------- /packages/template/vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/template-vite", 3 | "version": "7.8.1", 4 | "description": "Vite template for Electron Forge, gets you started with Vite really quickly", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/electron/forge", 8 | "directory": "packages/template/vite" 9 | }, 10 | "author": "caoxiemeihao", 11 | "license": "MIT", 12 | "main": "dist/ViteTemplate.js", 13 | "typings": "dist/ViteTemplate.d.ts", 14 | "engines": { 15 | "node": ">= 16.4.0" 16 | }, 17 | "dependencies": { 18 | "@electron-forge/shared-types": "7.8.1", 19 | "@electron-forge/template-base": "7.8.1", 20 | "fs-extra": "^10.0.0" 21 | }, 22 | "devDependencies": { 23 | "@electron-forge/test-utils": "7.8.1", 24 | "listr2": "^7.0.2", 25 | "vitest": "^3.1.3" 26 | }, 27 | "publishConfig": { 28 | "access": "public" 29 | }, 30 | "files": [ 31 | "dist", 32 | "src", 33 | "tmpl" 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /packages/template/vite/tmpl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "@electron/fuses": "^1.7.0", 4 | "@electron-forge/plugin-vite": "ELECTRON_FORGE/VERSION", 5 | "vite": "^5.0.12" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/template/vite/tmpl/preload.js: -------------------------------------------------------------------------------- 1 | // See the Electron documentation for details on how to use preload scripts: 2 | // https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts 3 | -------------------------------------------------------------------------------- /packages/template/vite/tmpl/renderer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file will automatically be loaded by vite and run in the "renderer" context. 3 | * To learn more about the differences between the "main" and the "renderer" context in 4 | * Electron, visit: 5 | * 6 | * https://electronjs.org/docs/tutorial/process-model 7 | * 8 | * By default, Node.js integration in this file is disabled. When enabling Node.js integration 9 | * in a renderer process, please be aware of potential security implications. You can read 10 | * more about security risks here: 11 | * 12 | * https://electronjs.org/docs/tutorial/security 13 | * 14 | * To enable Node.js integration in this file, open up `main.js` and enable the `nodeIntegration` 15 | * flag: 16 | * 17 | * ``` 18 | * // Create the browser window. 19 | * mainWindow = new BrowserWindow({ 20 | * width: 800, 21 | * height: 600, 22 | * webPreferences: { 23 | * nodeIntegration: true 24 | * } 25 | * }); 26 | * ``` 27 | */ 28 | 29 | import './index.css'; 30 | 31 | console.log('👋 This message is being logged by "renderer.js", included via Vite'); 32 | -------------------------------------------------------------------------------- /packages/template/vite/tmpl/vite.main.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | // https://vitejs.dev/config 4 | export default defineConfig({}); 5 | -------------------------------------------------------------------------------- /packages/template/vite/tmpl/vite.preload.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | // https://vitejs.dev/config 4 | export default defineConfig({}); 5 | -------------------------------------------------------------------------------- /packages/template/vite/tmpl/vite.renderer.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | // https://vitejs.dev/config 4 | export default defineConfig({}); 5 | -------------------------------------------------------------------------------- /packages/template/webpack-typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/template-webpack-typescript", 3 | "version": "7.8.1", 4 | "description": "Webpack-TypeScript template for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Shelley Vohr ", 7 | "license": "MIT", 8 | "main": "dist/WebpackTypeScriptTemplate.js", 9 | "typings": "dist/WebpackTypeScriptTemplate.d.ts", 10 | "engines": { 11 | "node": ">= 16.4.0" 12 | }, 13 | "dependencies": { 14 | "@electron-forge/shared-types": "7.8.1", 15 | "@electron-forge/template-base": "7.8.1", 16 | "fs-extra": "^10.0.0" 17 | }, 18 | "devDependencies": { 19 | "@electron-forge/core-utils": "7.8.1", 20 | "@electron-forge/maker-deb": "7.8.1", 21 | "@electron-forge/maker-rpm": "7.8.1", 22 | "@electron-forge/maker-squirrel": "7.8.1", 23 | "@electron-forge/maker-zip": "7.8.1", 24 | "@electron-forge/plugin-webpack": "7.8.1", 25 | "@electron-forge/test-utils": "7.8.1", 26 | "fast-glob": "^3.2.7", 27 | "fork-ts-checker-webpack-plugin": "^7.2.13", 28 | "listr2": "^7.0.2", 29 | "vitest": "^3.1.3" 30 | }, 31 | "files": [ 32 | "dist", 33 | "src", 34 | "tmpl" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/template/webpack-typescript/tmpl/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "node": true 6 | }, 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/eslint-recommended", 10 | "plugin:@typescript-eslint/recommended", 11 | "plugin:import/recommended", 12 | "plugin:import/electron", 13 | "plugin:import/typescript" 14 | ], 15 | "parser": "@typescript-eslint/parser" 16 | } 17 | -------------------------------------------------------------------------------- /packages/template/webpack-typescript/tmpl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "@electron-forge/plugin-webpack": "ELECTRON_FORGE/VERSION", 4 | "@typescript-eslint/eslint-plugin": "^5.0.0", 5 | "@typescript-eslint/parser": "^5.0.0", 6 | "@vercel/webpack-asset-relocator-loader": "1.7.3", 7 | "css-loader": "^6.0.0", 8 | "eslint": "^8.0.1", 9 | "eslint-plugin-import": "^2.25.0", 10 | "fork-ts-checker-webpack-plugin": "^7.2.13", 11 | "node-loader": "^2.0.0", 12 | "style-loader": "^3.0.0", 13 | "ts-loader": "^9.2.2", 14 | "ts-node": "^10.0.0", 15 | "typescript": "~4.5.4" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/template/webpack-typescript/tmpl/preload.ts: -------------------------------------------------------------------------------- 1 | // See the Electron documentation for details on how to use preload scripts: 2 | // https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts 3 | -------------------------------------------------------------------------------- /packages/template/webpack-typescript/tmpl/renderer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file will automatically be loaded by webpack and run in the "renderer" context. 3 | * To learn more about the differences between the "main" and the "renderer" context in 4 | * Electron, visit: 5 | * 6 | * https://electronjs.org/docs/latest/tutorial/process-model 7 | * 8 | * By default, Node.js integration in this file is disabled. When enabling Node.js integration 9 | * in a renderer process, please be aware of potential security implications. You can read 10 | * more about security risks here: 11 | * 12 | * https://electronjs.org/docs/tutorial/security 13 | * 14 | * To enable Node.js integration in this file, open up `main.js` and enable the `nodeIntegration` 15 | * flag: 16 | * 17 | * ``` 18 | * // Create the browser window. 19 | * mainWindow = new BrowserWindow({ 20 | * width: 800, 21 | * height: 600, 22 | * webPreferences: { 23 | * nodeIntegration: true 24 | * } 25 | * }); 26 | * ``` 27 | */ 28 | 29 | import './index.css'; 30 | 31 | console.log('👋 This message is being logged by "renderer.js", included via webpack'); 32 | -------------------------------------------------------------------------------- /packages/template/webpack-typescript/tmpl/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "allowJs": true, 5 | "module": "commonjs", 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "noImplicitAny": true, 9 | "sourceMap": true, 10 | "baseUrl": ".", 11 | "outDir": "dist", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "paths": { 15 | "*": ["node_modules/*"] 16 | } 17 | }, 18 | "include": ["src/**/*"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/template/webpack-typescript/tmpl/webpack.main.config.ts: -------------------------------------------------------------------------------- 1 | import type { Configuration } from 'webpack'; 2 | 3 | import { rules } from './webpack.rules'; 4 | import { plugins } from './webpack.plugins'; 5 | 6 | export const mainConfig: Configuration = { 7 | /** 8 | * This is the main entry point for your application, it's the first file 9 | * that runs in the main process. 10 | */ 11 | entry: './src/index.ts', 12 | // Put your normal webpack config below here 13 | module: { 14 | rules, 15 | }, 16 | plugins, 17 | resolve: { 18 | extensions: ['.js', '.ts', '.jsx', '.tsx', '.css', '.json'], 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /packages/template/webpack-typescript/tmpl/webpack.plugins.ts: -------------------------------------------------------------------------------- 1 | import type IForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; 2 | 3 | // eslint-disable-next-line @typescript-eslint/no-var-requires 4 | const ForkTsCheckerWebpackPlugin: typeof IForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); 5 | 6 | export const plugins = [ 7 | new ForkTsCheckerWebpackPlugin({ 8 | logger: 'webpack-infrastructure', 9 | }), 10 | ]; 11 | -------------------------------------------------------------------------------- /packages/template/webpack-typescript/tmpl/webpack.renderer.config.ts: -------------------------------------------------------------------------------- 1 | import type { Configuration } from 'webpack'; 2 | 3 | import { rules } from './webpack.rules'; 4 | import { plugins } from './webpack.plugins'; 5 | 6 | rules.push({ 7 | test: /\.css$/, 8 | use: [{ loader: 'style-loader' }, { loader: 'css-loader' }], 9 | }); 10 | 11 | export const rendererConfig: Configuration = { 12 | module: { 13 | rules, 14 | }, 15 | plugins, 16 | resolve: { 17 | extensions: ['.js', '.ts', '.jsx', '.tsx', '.css'], 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /packages/template/webpack-typescript/tmpl/webpack.rules.ts: -------------------------------------------------------------------------------- 1 | import type { ModuleOptions } from 'webpack'; 2 | 3 | export const rules: Required['rules'] = [ 4 | // Add support for native node modules 5 | { 6 | // We're specifying native_modules in the test because the asset relocator loader generates a 7 | // "fake" .node file which is really a cjs file. 8 | test: /native_modules[/\\].+\.node$/, 9 | use: 'node-loader', 10 | }, 11 | { 12 | test: /[/\\]node_modules[/\\].+\.(m?js|node)$/, 13 | parser: { amd: false }, 14 | use: { 15 | loader: '@vercel/webpack-asset-relocator-loader', 16 | options: { 17 | outputAssetBase: 'native_modules', 18 | }, 19 | }, 20 | }, 21 | { 22 | test: /\.tsx?$/, 23 | exclude: /(node_modules|\.webpack)/, 24 | use: { 25 | loader: 'ts-loader', 26 | options: { 27 | transpileOnly: true, 28 | }, 29 | }, 30 | }, 31 | ]; 32 | -------------------------------------------------------------------------------- /packages/template/webpack/.eslintignore: -------------------------------------------------------------------------------- 1 | tmpl -------------------------------------------------------------------------------- /packages/template/webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/template-webpack", 3 | "version": "7.8.1", 4 | "description": "Webpack template for Electron Forge, gets you started with Webpack really quickly", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/WebpackTemplate.js", 9 | "typings": "dist/WebpackTemplate.d.ts", 10 | "engines": { 11 | "node": ">= 16.4.0" 12 | }, 13 | "dependencies": { 14 | "@electron-forge/shared-types": "7.8.1", 15 | "@electron-forge/template-base": "7.8.1", 16 | "fs-extra": "^10.0.0" 17 | }, 18 | "devDependencies": { 19 | "@electron-forge/test-utils": "7.8.1", 20 | "listr2": "^7.0.2", 21 | "vitest": "^3.1.3" 22 | }, 23 | "publishConfig": { 24 | "access": "public" 25 | }, 26 | "files": [ 27 | "dist", 28 | "src", 29 | "tmpl" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /packages/template/webpack/tmpl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "@electron-forge/plugin-webpack": "ELECTRON_FORGE/VERSION", 4 | "@vercel/webpack-asset-relocator-loader": "1.7.3", 5 | "css-loader": "^6.0.0", 6 | "node-loader": "^2.0.0", 7 | "style-loader": "^3.0.0" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/template/webpack/tmpl/preload.js: -------------------------------------------------------------------------------- 1 | // See the Electron documentation for details on how to use preload scripts: 2 | // https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts 3 | -------------------------------------------------------------------------------- /packages/template/webpack/tmpl/renderer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file will automatically be loaded by webpack and run in the "renderer" context. 3 | * To learn more about the differences between the "main" and the "renderer" context in 4 | * Electron, visit: 5 | * 6 | * https://electronjs.org/docs/tutorial/process-model 7 | * 8 | * By default, Node.js integration in this file is disabled. When enabling Node.js integration 9 | * in a renderer process, please be aware of potential security implications. You can read 10 | * more about security risks here: 11 | * 12 | * https://electronjs.org/docs/tutorial/security 13 | * 14 | * To enable Node.js integration in this file, open up `main.js` and enable the `nodeIntegration` 15 | * flag: 16 | * 17 | * ``` 18 | * // Create the browser window. 19 | * mainWindow = new BrowserWindow({ 20 | * width: 800, 21 | * height: 600, 22 | * webPreferences: { 23 | * nodeIntegration: true 24 | * } 25 | * }); 26 | * ``` 27 | */ 28 | 29 | import './index.css'; 30 | 31 | console.log('👋 This message is being logged by "renderer.js", included via webpack'); 32 | -------------------------------------------------------------------------------- /packages/template/webpack/tmpl/webpack.main.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | /** 3 | * This is the main entry point for your application, it's the first file 4 | * that runs in the main process. 5 | */ 6 | entry: './src/main.js', 7 | // Put your normal webpack config below here 8 | module: { 9 | rules: require('./webpack.rules'), 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /packages/template/webpack/tmpl/webpack.renderer.config.js: -------------------------------------------------------------------------------- 1 | const rules = require('./webpack.rules'); 2 | 3 | rules.push({ 4 | test: /\.css$/, 5 | use: [{ loader: 'style-loader' }, { loader: 'css-loader' }], 6 | }); 7 | 8 | module.exports = { 9 | // Put your normal webpack config below here 10 | module: { 11 | rules, 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /packages/template/webpack/tmpl/webpack.rules.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | // Add support for native node modules 3 | { 4 | // We're specifying native_modules in the test because the asset relocator loader generates a 5 | // "fake" .node file which is really a cjs file. 6 | test: /native_modules[/\\].+\.node$/, 7 | use: 'node-loader', 8 | }, 9 | { 10 | test: /[/\\]node_modules[/\\].+\.(m?js|node)$/, 11 | parser: { amd: false }, 12 | use: { 13 | loader: '@vercel/webpack-asset-relocator-loader', 14 | options: { 15 | outputAssetBase: 'native_modules', 16 | }, 17 | }, 18 | }, 19 | // Put your webpack loader rules in this array. This is where you would put 20 | // your ts-loader configuration for instance: 21 | /** 22 | * Typescript Example: 23 | * 24 | * { 25 | * test: /\.tsx?$/, 26 | * exclude: /(node_modules|.webpack)/, 27 | * loaders: [{ 28 | * loader: 'ts-loader', 29 | * options: { 30 | * transpileOnly: true 31 | * } 32 | * }] 33 | * } 34 | */ 35 | ]; 36 | -------------------------------------------------------------------------------- /packages/utils/core-utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/core-utils", 3 | "version": "7.8.1", 4 | "description": "Core utilities for the Electron Forge packages", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/index.js", 9 | "typings": "dist/index.d.ts", 10 | "dependencies": { 11 | "@electron-forge/shared-types": "7.8.1", 12 | "@electron/rebuild": "^3.7.0", 13 | "@malept/cross-spawn-promise": "^2.0.0", 14 | "chalk": "^4.0.0", 15 | "debug": "^4.3.1", 16 | "find-up": "^5.0.0", 17 | "fs-extra": "^10.0.0", 18 | "log-symbols": "^4.0.0", 19 | "semver": "^7.2.1" 20 | }, 21 | "engines": { 22 | "node": ">= 16.4.0" 23 | }, 24 | "devDependencies": { 25 | "vitest": "^3.1.3" 26 | }, 27 | "files": [ 28 | "dist", 29 | "src" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/dummy_app/foo/null: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/utils/core-utils/spec/fixture/dummy_app/foo/null -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/dummy_app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "productName": "", 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "src/index.js", 7 | "scripts": { 8 | "start": "electron-forge start" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "MIT", 13 | "config": { 14 | "forge": { 15 | "packagerConfig": { 16 | "baz": {} 17 | }, 18 | "s3": {} 19 | } 20 | }, 21 | "devDependencies": { 22 | "electron": "1000.100.10" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/non-exact/node_modules/electron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron", 3 | "version": "4.0.9" 4 | } 5 | -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/npm-workspace/node_modules/electron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron", 3 | "version": "4.0.9" 4 | } 5 | -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/npm-workspace/package-lock.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/utils/core-utils/spec/fixture/npm-workspace/package-lock.json -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/npm-workspace/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "workspaces": [ 3 | "packages/subpackage" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/npm-workspace/packages/subpackage/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/utils/core-utils/spec/fixture/npm-workspace/packages/subpackage/.gitkeep -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/yarn-workspace/node_modules/electron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron", 3 | "version": "4.0.9" 4 | } 5 | -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/yarn-workspace/packages/electron-folder-in-node-modules/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/utils/core-utils/spec/fixture/yarn-workspace/packages/electron-folder-in-node-modules/.gitkeep -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/yarn-workspace/packages/electron-folder-in-node-modules/node_modules/electron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron", 3 | "version": "^12.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/yarn-workspace/packages/subpackage/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/utils/core-utils/spec/fixture/yarn-workspace/packages/subpackage/.gitkeep -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/yarn-workspace/packages/with-node-modules/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/utils/core-utils/spec/fixture/yarn-workspace/packages/with-node-modules/.gitkeep -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/yarn-workspace/packages/with-node-modules/node_modules/some-other-module-second/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "some-other-module-second", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/yarn-workspace/packages/with-node-modules/node_modules/some-other-module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "some-other-module-one", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /packages/utils/core-utils/spec/fixture/yarn-workspace/yarn.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electron/forge/4f879f53979c2d63be2774c3d04522ed969fe15f/packages/utils/core-utils/spec/fixture/yarn-workspace/yarn.lock -------------------------------------------------------------------------------- /packages/utils/core-utils/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './rebuild'; 2 | export * from './electron-version'; 3 | export * from './package-manager'; 4 | -------------------------------------------------------------------------------- /packages/utils/core-utils/src/remote-rebuild.ts: -------------------------------------------------------------------------------- 1 | import { rebuild, RebuildOptions } from '@electron/rebuild'; 2 | 3 | if (!process.send) { 4 | console.error('The remote rebuilder expects to be spawned with an IPC channel'); 5 | // eslint-disable-next-line no-process-exit 6 | process.exit(1); 7 | } 8 | 9 | const options: RebuildOptions = JSON.parse(process.argv[2]); 10 | 11 | const rebuilder = rebuild(options); 12 | 13 | rebuilder.lifecycle.on('module-found', () => process.send?.({ msg: 'module-found' })); 14 | rebuilder.lifecycle.on('module-done', () => process.send?.({ msg: 'module-done' })); 15 | 16 | rebuilder 17 | .then(() => { 18 | process.send?.({ msg: 'rebuild-done' }); 19 | // eslint-disable-next-line no-process-exit 20 | return process.exit(0); 21 | }) 22 | .catch((err) => { 23 | process.send?.({ 24 | msg: 'rebuild-error', 25 | err: { 26 | message: err.message, 27 | stack: err.stack, 28 | }, 29 | }); 30 | // eslint-disable-next-line no-process-exit 31 | process.exit(0); 32 | }); 33 | -------------------------------------------------------------------------------- /packages/utils/test-utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/test-utils", 3 | "version": "7.8.1", 4 | "description": "Helper utilities for the Electron Forge testsuite", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Mark Lee", 7 | "license": "MIT", 8 | "main": "dist/index.js", 9 | "typings": "dist/index.d.ts", 10 | "dependencies": { 11 | "@malept/cross-spawn-promise": "^2.0.0" 12 | }, 13 | "engines": { 14 | "node": ">= 16.4.0" 15 | }, 16 | "publishConfig": { 17 | "access": "public" 18 | }, 19 | "files": [ 20 | "dist", 21 | "src" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /packages/utils/tracer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/tracer", 3 | "version": "7.8.1", 4 | "description": "Tracing helpers for Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/index.js", 9 | "typings": "dist/index.d.ts", 10 | "dependencies": { 11 | "chrome-trace-event": "^1.0.3" 12 | }, 13 | "engines": { 14 | "node": ">= 14.17.5" 15 | }, 16 | "publishConfig": { 17 | "access": "public" 18 | }, 19 | "files": [ 20 | "dist", 21 | "src" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /packages/utils/types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/shared-types", 3 | "version": "7.8.1", 4 | "description": "Shared types across Electron Forge", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/index.js", 9 | "typings": "dist/index.d.ts", 10 | "dependencies": { 11 | "@electron-forge/tracer": "7.8.1", 12 | "@electron/packager": "^18.3.5", 13 | "@electron/rebuild": "^3.7.0", 14 | "listr2": "^7.0.2" 15 | }, 16 | "engines": { 17 | "node": ">= 16.4.0" 18 | }, 19 | "publishConfig": { 20 | "access": "public" 21 | }, 22 | "files": [ 23 | "dist", 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /packages/utils/web-multi-logger/README.md: -------------------------------------------------------------------------------- 1 | # Web Multi Logger 2 | 3 | > Display multiple streams of logs in one window 4 | 5 | This module allows you to pipe multiple logically separated streams of logs into 6 | multiple visually separated views in a web console. It comes with full ANSI 7 | support so you can pipe anything that would work in a Terminal into this tool 8 | as well. 9 | 10 | ## Usage 11 | 12 | ```javascript 13 | import Logger from '@electron-forge/web-multi-logger'; 14 | 15 | const logger = new Logger(); 16 | 17 | const serverTab = logger.createTab('server'); 18 | const frontEndTab = logger.createTab('front_end'); 19 | 20 | runServerWithLogger(serverTab); 21 | runFrontEndWithLogger(frontEndTab); 22 | 23 | // Navigate to http://localhost:9000 in your browser 24 | ``` 25 | -------------------------------------------------------------------------------- /packages/utils/web-multi-logger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@electron-forge/web-multi-logger", 3 | "version": "7.8.1", 4 | "description": "Display multiple streams of logs in one window", 5 | "repository": "https://github.com/electron/forge", 6 | "author": "Samuel Attard", 7 | "license": "MIT", 8 | "main": "dist/Logger.js", 9 | "typings": "dist/Logger.d.ts", 10 | "dependencies": { 11 | "express": "^4.17.1", 12 | "express-ws": "^5.0.2", 13 | "xterm": "^4.9.0", 14 | "xterm-addon-fit": "^0.5.0", 15 | "xterm-addon-search": "^0.8.0" 16 | }, 17 | "engines": { 18 | "node": ">= 16.4.0" 19 | }, 20 | "publishConfig": { 21 | "access": "public" 22 | }, 23 | "files": [ 24 | "dist", 25 | "src", 26 | "static" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /packages/utils/web-multi-logger/src/Log.ts: -------------------------------------------------------------------------------- 1 | export default class Log { 2 | constructor(public line: string, public timestamp: Date) {} 3 | } 4 | -------------------------------------------------------------------------------- /packages/utils/web-multi-logger/src/Tab.ts: -------------------------------------------------------------------------------- 1 | import ews from 'express-ws'; 2 | 3 | import Log from './Log'; 4 | 5 | let idCounter = 1; 6 | 7 | export default class Tab { 8 | private logs: Log[] = []; 9 | 10 | private id: number; 11 | 12 | constructor(public name: string, private ws: ews.Instance) { 13 | this.id = idCounter; 14 | idCounter += 1; 15 | } 16 | 17 | /** 18 | * Log a line to the web UI, a new line is automatically appended to the line 19 | */ 20 | log(line: string): void { 21 | const log = new Log(line, new Date()); 22 | this.logs.push(log); 23 | 24 | for (const client of this.ws.getWss().clients) { 25 | client.send( 26 | JSON.stringify({ 27 | tab: this.id, 28 | payload: log, 29 | }) 30 | ); 31 | } 32 | } 33 | 34 | private toJSON() { 35 | return { 36 | id: this.id, 37 | name: this.name, 38 | logs: this.logs, 39 | }; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tools/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "import/no-extraneous-dependencies": "off", 4 | "no-await-in-loop": "off", 5 | "no-console": "off", 6 | "no-continue": "off", 7 | "no-restricted-syntax": "off" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tools/doc-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typedoc-forge-custom-sidebar-theme", 3 | "version": "1.0.0", 4 | "main": "dist/index.js", 5 | "repository": "", 6 | "license": "MIT", 7 | "keywords": [ 8 | "typedoc-theme", 9 | "custom-sidebar" 10 | ], 11 | "engines": { 12 | "node": ">= 16.4.0" 13 | }, 14 | "devDependencies": { 15 | "typescript": "^4.6.3" 16 | }, 17 | "peerDependencies": { 18 | "typedoc": "^0.22.15" 19 | }, 20 | "scripts": { 21 | "build": "tsc", 22 | "predocs": "tsc", 23 | "docs": "typedoc src --plugin dist/index.js" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tools/doc-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src"], 3 | 4 | "compilerOptions": { 5 | "target": "ES2021", 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "forceConsistentCasingInFileNames": true, 9 | "skipLibCheck": true, 10 | "strict": true, 11 | "outDir": "dist", 12 | "esModuleInterop": true, 13 | 14 | "jsx": "react", 15 | "jsxFactory": "JSX.createElement", 16 | "jsxFragmentFactory": "JSX.Fragment" 17 | }, 18 | "exclude": ["src/assets"] 19 | } 20 | -------------------------------------------------------------------------------- /tools/doc-plugin/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | typescript@^4.6.3: 6 | version "4.8.4" 7 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" 8 | integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== 9 | -------------------------------------------------------------------------------- /tools/fix-deps.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'node:path'; 2 | 3 | import * as fs from 'fs-extra'; 4 | 5 | import { getPackageInfo } from './utils'; 6 | 7 | (async () => { 8 | const packages = await getPackageInfo(); 9 | 10 | const baseJson = await fs.readJson(path.resolve(__dirname, '..', 'package.json')); 11 | 12 | const allDeps = { 13 | ...baseJson.dependencies, 14 | ...baseJson.devDependencies, 15 | ...baseJson.optionalDependencies, 16 | }; 17 | 18 | for (const p of packages) { 19 | const json = await fs.readJson(path.resolve(p.path, 'package.json')); 20 | 21 | for (const key of ['dependencies', 'devDependencies', 'optionalDependencies']) { 22 | const deps = json[key]; 23 | if (!deps) continue; 24 | 25 | for (const depKey in deps) { 26 | if (depKey.startsWith('@electron-forge/')) continue; 27 | 28 | if (deps[depKey] !== allDeps[depKey]) { 29 | console.error(p.name, depKey, deps[depKey], '-->', allDeps[depKey]); 30 | deps[depKey] = allDeps[depKey]; 31 | } 32 | } 33 | } 34 | 35 | await fs.writeJson(path.resolve(p.path, 'package.json'), json, { 36 | spaces: 2, 37 | }); 38 | } 39 | })().catch(console.error); 40 | -------------------------------------------------------------------------------- /tools/silent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Silences warnings and other stdio logs produced from commands 3 | * 4 | * It does not silence errors. 5 | */ 6 | 7 | const { spawn } = require('@malept/cross-spawn-promise'); 8 | 9 | const [cmd, ...args] = process.argv.slice(2); 10 | 11 | spawn(cmd, args, { 12 | stdio: 'pipe', 13 | }); 14 | -------------------------------------------------------------------------------- /tools/test-clear.ts: -------------------------------------------------------------------------------- 1 | import os from 'node:os'; 2 | import path from 'node:path'; 3 | 4 | import chalk from 'chalk'; 5 | import glob from 'fast-glob'; 6 | import fs from 'fs-extra'; 7 | 8 | (async () => { 9 | // https://github.com/electron/forge/blob/v7.2.0/packages/utils/test-utils/src/index.ts#L24 10 | const dirs = await glob(path.resolve(os.tmpdir(), 'electron-forge-test-*')); 11 | 12 | if (dirs.length) { 13 | for (const dir of dirs) { 14 | console.log('Clean up the test dir:', dir); 15 | 16 | // Remove the tmp files generated by slow tests 17 | // see here 👉 https://github.com/electron/forge/pull/3468#issuecomment-1920805240 18 | await fs.remove(dir); 19 | } 20 | } else { 21 | console.log(chalk.gray('There is no "electron-forge-test-*" dir that needs to be cleaned.')); 22 | } 23 | })(); 24 | -------------------------------------------------------------------------------- /tools/test-dist.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'node:path'; 2 | 3 | import chalk from 'chalk'; 4 | import * as fs from 'fs-extra'; 5 | 6 | const BASE_DIR = path.resolve(__dirname, '..'); 7 | const PACKAGES_DIR = path.resolve(BASE_DIR, 'packages'); 8 | 9 | (async () => { 10 | const dirsToCheck: string[] = []; 11 | 12 | for (const subDir of await fs.readdir(PACKAGES_DIR)) { 13 | const subDirPath = path.resolve(PACKAGES_DIR, subDir); 14 | const stat = await fs.lstat(subDirPath); 15 | if (stat.isDirectory()) { 16 | for (const packageDir of await fs.readdir(subDirPath)) { 17 | const packageDirPath = path.resolve(PACKAGES_DIR, subDir, packageDir); 18 | const stat = await fs.lstat(packageDirPath); 19 | if (stat.isDirectory()) { 20 | dirsToCheck.push(packageDirPath); 21 | } 22 | } 23 | } 24 | } 25 | 26 | let bad = false; 27 | for (const dir of dirsToCheck) { 28 | const pj = await fs.readJson(path.resolve(dir, 'package.json')); 29 | if (pj.name === '@electron-forge/cli') continue; 30 | if (!(await fs.pathExists(path.resolve(dir, pj.main)))) { 31 | console.error(`${chalk.cyan(`[${pj.name}]`)}:`, chalk.red(`Main entry not found (${pj.main})`)); 32 | bad = true; 33 | } 34 | if (!pj.typings || !(await fs.pathExists(path.resolve(dir, pj.typings)))) { 35 | console.error(`${chalk.cyan(`[${pj.name}]`)}:`, chalk.red(`Typings entry not found (${pj.typings})`)); 36 | bad = true; 37 | } 38 | } 39 | 40 | if (bad) { 41 | process.exit(1); 42 | } 43 | })().catch(console.error); 44 | -------------------------------------------------------------------------------- /tools/update-node-version.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ts-node 2 | 3 | import path from 'node:path'; 4 | 5 | import { readJsonSync, writeJsonSync } from 'fs-extra'; 6 | 7 | import { getPackageInfoSync } from './utils'; 8 | 9 | const nodeVersion = process.argv[2]; 10 | 11 | for (const { path: packagePath } of getPackageInfoSync()) { 12 | const filename = path.join(packagePath, 'package.json'); 13 | const packageJSON = readJsonSync(filename); 14 | packageJSON.engines.node = `>= ${nodeVersion}`; 15 | writeJsonSync(filename, packageJSON, { spaces: 2 }); 16 | } 17 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2021", 5 | "outDir": "dist", 6 | "lib": ["dom", "ES2021"], 7 | "inlineSourceMap": true, 8 | "rootDir": "src", 9 | "experimentalDecorators": true, 10 | "strict": true, 11 | "esModuleInterop": true, 12 | "declaration": true, 13 | "composite": true, 14 | "declarationMap": true, 15 | "resolveJsonModule": true 16 | }, 17 | "exclude": ["node_modules", "dist", "test", "index.ts", "spec", "tmpl"] 18 | } 19 | -------------------------------------------------------------------------------- /tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "//": "⚠️ NOTE: this file is only used for tests, individual packages have their own tsconfig.json files generated by `tools/gen-tsconfigs.ts`", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "target": "ES2021", 6 | "outDir": "dist", 7 | "lib": ["dom", "ES2021"], 8 | "sourceMap": true, 9 | "experimentalDecorators": true, 10 | "strict": true, 11 | "esModuleInterop": true, 12 | "declaration": true, 13 | "declarationMap": true, 14 | "typeRoots": ["./typings", "./node_modules/@types"] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /typedoc.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://typedoc.org/schema.json", 3 | "excludeInternal": true 4 | } 5 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://typedoc.org/schema.json", 3 | "entryPointStrategy": "packages", 4 | "entryPoints": ["packages/api/core", "packages/maker/*", "packages/plugin/*", "packages/plugin/*", "packages/publisher/*", "packages/utils/types"] 5 | } 6 | -------------------------------------------------------------------------------- /typings/@doyensec/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@doyensec/electronegativity'; 2 | -------------------------------------------------------------------------------- /typings/cross-spawn/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'cross-spawn/lib/util/resolveCommand'; 2 | -------------------------------------------------------------------------------- /typings/electron-windows-store/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'electron-windows-store' { 2 | const run: (opts: any) => Promise; 3 | export default run; 4 | } 5 | 6 | declare module 'electron-windows-store/lib/sign' { 7 | export const isValidPublisherName: (name: string) => boolean; 8 | export const makeCert: (opts: MakerCertOptions) => Promise; 9 | 10 | interface MakerCertOptions { 11 | publisherName: string; 12 | certFilePath: string; 13 | certFileName: string; 14 | install: boolean; 15 | program: any; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /typings/parse-author/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'parse-author' { 2 | type AuthorType = 3 | | string 4 | | { 5 | name: string; 6 | } 7 | | undefined; 8 | interface ParseAuthor { 9 | (author: AuthorType): AuthorType; 10 | } 11 | const parseAuthor: ParseAuthor; 12 | export default parseAuthor; 13 | } 14 | -------------------------------------------------------------------------------- /typings/sudo-prompt/index.d.ts: -------------------------------------------------------------------------------- 1 | import { PromiseWithChild } from 'node:child_process'; 2 | 3 | // Copied from https://github.com/jorangreef/sudo-prompt/pull/124 4 | // TODO: Remove this if/when that PR gets merged/released 5 | declare module 'sudo-prompt' { 6 | namespace exec { 7 | function __promisify__(command: string): PromiseWithChild<{ stdout: string; stderr: string }>; 8 | function __promisify__( 9 | command: string, 10 | options: ((error?: Error, stdout?: TBuffer, stderr?: TBuffer) => void) | { name?: string; icns?: string; env?: Record } 11 | ): PromiseWithChild<{ stdout: TBuffer; stderr: TBuffer }>; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /vitest.config.mts: -------------------------------------------------------------------------------- 1 | /// 2 | import { defineConfig } from 'vitest/config'; 3 | 4 | export default defineConfig({ 5 | test: { 6 | clearMocks: true, 7 | exclude: ['**/.links/**', '**/node_modules/**'], 8 | fileParallelism: false, 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /vitest.workspace.mts: -------------------------------------------------------------------------------- 1 | import { defineWorkspace } from 'vitest/config'; 2 | 3 | export default defineWorkspace([ 4 | { 5 | extends: './vitest.config.mts', 6 | test: { 7 | include: ['**/spec/**/*.spec.ts'], 8 | exclude: ['**/spec/**/*.slow.spec.ts'], 9 | name: 'fast', 10 | }, 11 | }, 12 | { 13 | extends: './vitest.config.mts', 14 | test: { 15 | include: ['**/spec/**/*.slow.spec.ts'], 16 | name: 'slow', 17 | hookTimeout: 120000, 18 | testTimeout: 120000, 19 | }, 20 | }, 21 | ]); 22 | --------------------------------------------------------------------------------