import * as path from 'node:path'; import { FuseV1Options, FuseVersion } from '@electron/fuses'; import { FusesPlugin } from '@electron-forge/plugin-fuses'; import type { ForgeConfig } from '@electron-forge/shared-types'; import packageJson from './package.json'; import { maybeFetchContributors } from './tools/contributors'; import { populateReleases } from './tools/fetch-releases'; import { mainConfig } from './tools/webpack/webpack.main.config'; import { rendererConfig } from './tools/webpack/webpack.renderer.config'; const { version } = packageJson; const iconDir = path.resolve(__dirname, 'assets', 'icons'); const root = process.cwd(); const commonLinuxConfig = { categories: ['Development', 'Utility'], icon: { '1024x1024': path.resolve(iconDir, 'fiddle.png'), scalable: path.resolve(iconDir, 'fiddle.svg'), }, mimeType: ['x-scheme-handler/electron-fiddle'], }; const requirements = path.resolve(__dirname, 'tools/certs/requirements.txt'); const config: ForgeConfig = { hooks: { generateAssets: async () => { await Promise.all([populateReleases(), maybeFetchContributors(true)]); }, }, plugins: [ { name: '@electron-forge/plugin-webpack', config: { devContentSecurityPolicy: "default-src 'none'; img-src 'self' https: data:; media-src 'none'; child-src 'self'; object-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self' https:; font-src 'self' https:;", devServer: { // Disallow browser from opening/reloading with HMR in development mode. open: false, liveReload: false, hot: 'only', }, mainConfig: mainConfig, renderer: { config: rendererConfig, entryPoints: [ { html: path.join(root, './static/index.html'), js: path.join(root, './src/renderer/main.tsx'), name: 'main_window', preload: { js: path.join(root, 'src/preload/preload.ts'), }, }, ], }, }, }, new FusesPlugin({ version: FuseVersion.V1, [FuseV1Options.RunAsNode]: false, [FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false, [FuseV1Options.EnableNodeCliInspectArguments]: false, [FuseV1Options.OnlyLoadAppFromAsar]: true, }), ], packagerConfig: { name: 'Electron Fiddle', executableName: 'electron-fiddle', asar: true, icon: path.resolve(__dirname, 'assets', 'icons', 'fiddle'), appBundleId: 'com.electron.fiddle', usageDescription: { Camera: 'Access is needed by certain built-in fiddles in addition to any custom fiddles that use the Camera', Microphone: 'Access is needed by certain built-in fiddles in addition to any custom fiddles that use the Microphone', Calendars: 'Access is needed by certain built-in fiddles in addition to any custom fiddles that may access Calendars', Contacts: 'Access is needed by certain built-in fiddles in addition to any custom fiddles that may access Contacts', Reminders: 'Access is needed by certain built-in fiddles in addition to any custom fiddles that may access Reminders', }, appCategoryType: 'public.app-category.developer-tools', protocols: [ { name: 'Electron Fiddle Launch Protocol', schemes: ['electron-fiddle'], }, ], win32metadata: { CompanyName: 'Electron Community', OriginalFilename: 'Electron Fiddle', }, osxSign: { identity: 'Developer ID Application: OpenJS Foundation, Inc. (UY52UFTVTM)', optionsForFile: (filePath) => ['(Plugin).app', '(GPU).app', '(Renderer).app'].some((helper) => filePath.includes(helper), ) ? { requirements } : { entitlements: 'static/entitlements.plist', requirements, }, }, }, makers: [ { name: '@electron-forge/maker-squirrel', platforms: ['win32'], config: (arch: string) => ({ name: 'electron-fiddle', authors: 'Electron Community', exe: 'electron-fiddle.exe', iconUrl: 'https://raw.githubusercontent.com/electron/fiddle/0119f0ce697f5ff7dec4fe51f17620c78cfd488b/assets/icons/fiddle.ico', loadingGif: './assets/loading.gif', noMsi: true, setupExe: `electron-fiddle-${version}-win32-${arch}-setup.exe`, setupIcon: path.resolve(iconDir, 'fiddle.ico'), signWithParams: `/sha1 ${process.env.CERT_FINGERPRINT} /tr http://timestamp.digicert.com /td SHA256 /fd SHA256`, }), }, { name: '@electron-forge/maker-zip', platforms: ['darwin'], config: {}, }, { name: '@electron-forge/maker-deb', platforms: ['linux'], config: commonLinuxConfig, }, { name: '@electron-forge/maker-rpm', platforms: ['linux'], config: commonLinuxConfig, }, { name: '@reforged/maker-appimage', platforms: ['linux'], config: { options: { categories: commonLinuxConfig.categories, }, }, }, ], publishers: [ { name: '@electron-forge/publisher-github', config: { repository: { owner: 'electron', name: 'fiddle', }, draft: true, prerelease: false, generateReleaseNotes: true, }, }, ], }; function notarizeMaybe() { if (process.platform !== 'darwin') { return; } if (!process.env.CI && !process.env.FORCE_NOTARIZATION) { // Not in CI, skipping notarization console.log('Not in CI, skipping notarization'); return; } if (!process.env.APPLE_ID || !process.env.APPLE_ID_PASSWORD) { console.warn( 'Should be notarizing, but environment variables APPLE_ID or APPLE_ID_PASSWORD are missing!', ); return; } config.packagerConfig!.osxNotarize = { appleId: process.env.APPLE_ID, appleIdPassword: process.env.APPLE_ID_PASSWORD, teamId: 'UY52UFTVTM', }; } notarizeMaybe(); // Finally, export it export default config;