Files
flying-jib/forge.config.cjs
T
2026-07-31 02:05:43 -04:00

183 lines
4.7 KiB
JavaScript

/**
* Electron Forge config for Flying Jib desktop client.
* Packages Electron shell + Bare backend deps; CLI standalones remain separate.
*/
'use strict'
const path = require('path')
const fs = require('fs')
const pkg = require('./package.json')
const appName = pkg.productName || pkg.name || 'Flying Jib'
function resolvePackageTarget() {
const argv = process.argv
const flag = (name) => {
const i = argv.indexOf(name)
return i >= 0 && argv[i + 1] ? argv[i + 1] : null
}
const platform = process.env.FJ_PACKAGE_PLATFORM || flag('--platform') || process.platform
const arch = process.env.FJ_PACKAGE_ARCH || flag('--arch') || process.arch
return { platform, arch }
}
const packageTarget = resolvePackageTarget()
const packageHost = `${packageTarget.platform}-${packageTarget.arch}`
const IGNORE_PREFIXES = [
'/.git',
'/.gitea',
'/.github',
'/.cursor',
'/out',
'/dist',
'/deploy',
'/test',
'/agent',
'/living_docs',
'/developer_docs',
'/user_docs',
'/scripts',
'/.cache',
'/node_modules/electron',
'/node_modules/electron-',
'/node_modules/@electron',
'/node_modules/@electron-forge',
'/node_modules/bare-build',
'/node_modules/brittle',
'/node_modules/typescript',
'/node_modules/prettier',
'/node_modules/esbuild',
'/node_modules/@esbuild',
'/node_modules/webpack',
'/node_modules/@types'
]
const IGNORE_REGEX = [
/^\/node_modules\/bare-build-/,
/^\/node_modules\/@esbuild\//,
/\.md$/i,
/\.map$/,
/\.d\.ts$/,
/^\/\.env/,
/^\/package-lock\.json$/,
/^\/node_modules\/[^/]+\/test\//,
/^\/node_modules\/[^/]+\/tests\//,
/^\/node_modules\/[^/]+\/docs\//,
/^\/node_modules\/[^/]+\/example\//,
/^\/node_modules\/[^/]+\/examples\//
]
function isForeignPrebuild(file) {
const marker = '/prebuilds/'
const idx = file.indexOf(marker)
if (idx === -1) return false
const host = file.slice(idx + marker.length).split('/')[0]
if (!host) return false
if (host.startsWith('android') || host.startsWith('ios') || host.includes('simulator')) return true
return host !== packageHost
}
function shouldIgnore(file) {
if (!file) return false
if (file === '/package.json') return false
for (const p of IGNORE_PREFIXES) {
if (file === p || file.startsWith(p + '/') || file.startsWith(p)) return true
}
for (const re of IGNORE_REGEX) {
if (re.test(file)) return true
}
if (isForeignPrebuild(file)) return true
return false
}
function stripBuildPath(buildPath) {
const drop = ['agent', 'living_docs', 'developer_docs', 'user_docs', 'test', 'scripts', '.gitea']
for (const rel of drop) {
const p = path.join(buildPath, rel)
try {
if (fs.existsSync(p)) fs.rmSync(p, { recursive: true, force: true })
} catch {
// ignore
}
}
}
module.exports = {
packagerConfig: {
name: appName,
executableName: 'flying-jib',
appBundleId: 'app.flyingjib.desktop',
asar: true,
// Bare child cannot execute from inside asar — keep runtime + app graph on disk.
asarUnpack: [
'electron/backend.mjs',
'app.js',
'lib/**/*',
'build/**/*',
'node_modules/bare-runtime/**/*',
'node_modules/bare-runtime-*/**/*',
'node_modules/**/*.node',
'node_modules/**/prebuilds/**/*'
],
prune: false,
ignore: shouldIgnore,
osxSign: false,
afterCopy: [
(buildPath, _electronVersion, _platform, _arch, callback) => {
try {
stripBuildPath(buildPath)
callback()
} catch (err) {
callback(err)
}
}
]
},
rebuildConfig: {
onlyModules: []
},
makers: [
{
name: '@electron-forge/maker-zip',
platforms: ['darwin', 'linux', 'win32']
},
{
name: '@electron-forge/maker-dmg',
platforms: ['darwin'],
config: {
name: `${appName}`,
format: 'ULFO'
}
},
{
name: '@electron-forge/maker-squirrel',
platforms: ['win32'],
config: {
name: 'FlyingJib',
authors: 'Flying Jib',
exe: 'flying-jib.exe'
}
}
],
hooks: {
packageAfterCopy: async (_forgeConfig, buildPath) => {
const pkgPath = path.join(buildPath, 'package.json')
const appPkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
appPkg.main = 'electron/main.cjs'
delete appPkg.devDependencies
delete appPkg.scripts
if (appPkg.dependencies) {
for (const name of ['bare-build', 'pear-electron', 'pear-bridge', '@electron-forge/cli']) {
delete appPkg.dependencies[name]
}
}
fs.writeFileSync(pkgPath, JSON.stringify(appPkg, null, 2) + '\n')
stripBuildPath(buildPath)
},
preMake: async () => {
fs.rmSync(path.join(__dirname, 'out', 'make'), { recursive: true, force: true })
}
}
}