-
-
Notifications
You must be signed in to change notification settings - Fork 88
Expand file tree
/
Copy pathelectron-builder.config.mjs
More file actions
339 lines (290 loc) · 12.8 KB
/
electron-builder.config.mjs
File metadata and controls
339 lines (290 loc) · 12.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
import { readFileSync, writeFileSync, unlinkSync, existsSync, renameSync } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { execSync } from 'child_process';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const packageJson = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8'));
const { name, version, description, author } = packageJson;
export default {
appId: 'tv.megacubo.app',
productName: 'Megacubo',
copyright: `Copyright © ${new Date().getFullYear()} ${author.name}`,
npmRebuild: false,
nodeGypRebuild: false,
buildDependenciesFromSource: false,
// Settings to prevent automatic inclusion of dependencies
files: [
// Arquivos JavaScript compilados essenciais
'www/nodejs/dist/main.js',
'www/nodejs/dist/electron.js',
'www/nodejs/dist/preload.js',
'www/nodejs/dist/worker.js',
'www/nodejs/dist/updater-worker.js',
'www/nodejs/dist/EPGManager.js',
'www/nodejs/dist/mpegts-processor-worker.js',
'www/nodejs/dist/premium.js',
// Arquivos Svelte compilados
'www/nodejs/dist/App.js',
'www/nodejs/dist/capacitor.js',
// Essential data
'www/nodejs/dist/dayjs-locale/**',
'www/nodejs/dist/defaults/**',
// Source files and configuration
'www/nodejs/main.mjs',
'www/nodejs/package.json',
'www/nodejs/lang/**/*',
'www/nodejs/modules/**/*',
'www/nodejs/renderer/**/*',
// Critical exclusions
'!www/nodejs/dist/electron.js.map',
'!www/nodejs/dist/main.js.map',
'!www/nodejs/dist/preload.js.map',
'!www/nodejs/dist/*.worker.js.map',
'!www/nodejs/modules/smart-recommendations/trias/**/*',
// AGGRESSIVE disk space exclusions
'!android/**', // Exclude complete android directory
'!**/android/**', // Exclude ANY android folder anywhere
'!releases/**', // Exclude releases (APKs, old builds)
'!premium_files/**', // Exclude premium files not needed for build
'!dist_optimized/**', // Exclude old optimized builds
'!patches/**', // Exclude patches
'!assets/**', // Exclude unused assets in Electron
'!build/**', // Exclude build folder (except what we need)
'!build/cast_channel.proto', // KEEP only this necessary file
'!build/ffmpeg/**', // KEEP FFmpeg
// Native library exclusions
'!**/*.so', // Exclude Linux native libraries (.so)
'!**/*.dylib', // Exclude macOS libraries (.dylib)
'!**/*.dll', // Exclude Windows libraries (.dll) - only necessary ones will be included
'!**/*.a', // Exclude static libraries
'!**/*.lib', // Exclude Windows libraries
// Development exclusions
'!node_modules/**', // Exclude ANY node_modules from root
'!**/build/**', // Exclude unnecessary build folders
'!www/nodejs/dist/node_modules/**', // Exclude ALL node_modules dependencies
'!**/*.map', // Exclude source maps
'!**/*.ts', // Exclude TypeScript files
'!**/*.test.*', // Exclude test files
'!docs/**', // Exclude documentation
'!*.md', // Exclude markdown files
'!*.cmd', // Exclude command scripts
'!*.bat', // Exclude batch files
'!*.log', // Exclude log files
'!*.txt', // Exclude non-essential text files
'!*.aar', // Exclude Android .aar files
'!*.apk', // Exclude Android .apk files
'!*.zip', // Exclude ZIP files
'!*.exe', // Exclude Windows executables (except necessary ones)
'!fmpeg-kit-16KB-6.0.aar', // Exclude specific FFmpeg Android file
'!fnr.exe', // Excluir Find and Replace tool
],
// Platform-specific settings
win: {
target: [
{
target: 'nsis',
arch: ['x64', 'ia32']
},
{
target: 'msi',
arch: ['x64', 'ia32']
}
],
verifyUpdateCodeSignature: false
},
nsis: {
oneClick: false,
perMachine: false,
allowToChangeInstallationDirectory: true,
deleteAppDataOnUninstall: false,
runAfterFinish: true,
include: null,
script: null
},
mac: {
target: [
{
target: 'dmg',
arch: ['x64', 'arm64']
},
{
target: 'zip',
arch: ['x64', 'arm64']
}
],
icon: 'www/nodejs/default_icon.icns',
category: 'public.app-category.video',
darkModeSupport: true,
hardenedRuntime: false,
gatekeeperAssess: false
},
// Simplified hook - since node_modules is already excluded, this hook has limited effect
// but it can be useful for other file types
onNodeModuleFile: (file) => {
// As node_modules is excluded in the files configuration,
// this hook has little effect, but we keep it for safety
return 'exclude';
},
// Build hooks (optimized solution)
beforeBuild: async (context) => {
console.log('🔨 Starting Megacubo build...');
console.log('📦 Platform:', context.platform.nodeName);
console.log('🏗️ Architecture:', context.arch);
console.log('📋 Build type:', context.targets.map(t => t.name).join(', '));
},
afterPack: async (context) => {
console.error('🔥🔥🔥 AFTERPACK HOOK EXECUTED! 🔥🔥🔥');
console.error('✅ Build finished - optimized files!');
console.error('🔍 DEBUG: afterPack hook called with context:', {
platform: context.platform?.nodeName,
appOutDir: context.appOutDir,
electronDistPath: context.electronDistPath
});
// Compile premium.js to bytecode using Electron (ensures compatibility)
console.log('🔒 Compiling premium.js to bytecode using Electron runtime...');
const appOutDir = context.appOutDir;
const premiumJsPath = join(appOutDir, 'dist', 'premium.js');
const premiumJscPath = join(appOutDir, 'dist', 'premium.jsc');
// Get Electron executable path for current platform
let electronExecutable;
switch (context.platform.nodeName) {
case 'win32':
electronExecutable = join(context.electronDistPath, 'electron.exe');
break;
case 'darwin':
electronExecutable = join(context.electronDistPath, 'Electron.app', 'Contents', 'MacOS', 'Electron');
break;
default: // linux
electronExecutable = join(context.electronDistPath, 'electron');
}
console.log(` 📍 Electron executable: ${electronExecutable}`);
console.log(` 📁 App directory: ${appOutDir}`);
if (existsSync(premiumJsPath)) {
try {
// Use Electron to compile bytenode (ensures V8 compatibility)
const compileCommand = `"${electronExecutable}" -e "
const path = require('path');
const bytenode = require(path.join(process.cwd(), 'dist', 'node_modules', 'bytenode'));
const premiumPath = path.join(process.cwd(), 'dist', 'premium.js');
const jscPath = path.join(process.cwd(), 'dist', 'premium.jsc');
bytenode.compileFile(premiumPath, jscPath);
console.log('✅ premium.jsc compiled successfully with Electron');
"`;
console.log(' 🔨 Running bytenode compilation...');
execSync(compileCommand, {
cwd: appOutDir,
stdio: 'inherit',
env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' }
});
// Verify compilation succeeded
if (existsSync(premiumJscPath)) {
// Remove the original JavaScript file
unlinkSync(premiumJsPath);
console.log(' ✅ Premium bytecode protection applied successfully');
console.log(' 🗑️ Original premium.js removed from distribution');
} else {
throw new Error('premium.jsc was not created');
}
} catch (error) {
console.error(' ❌ ERROR: Failed to compile premium.jsc with Electron:', error.message);
console.error(' 📝 This build will continue but premium code is not protected!');
// Don't fail the build, just warn - premium still works without protection
}
} else {
console.log(' ⚠️ premium.js not found - skipping bytecode compilation');
}
// Fix AppImage sandbox issues on Linux by creating a wrapper script
if (context.platform.nodeName === 'linux') {
console.log(' 🛠️ Creating AppImage sandbox fix wrapper...');
const appOutDir = context.appOutDir;
const electronBinPath = join(appOutDir, 'megacubo'); // Default electron executable name
// Create a wrapper script that launches electron with --no-sandbox
const wrapperScript = `#!/bin/bash
# AppImage wrapper to fix sandbox issues on Linux VMs
export ELECTRON_DISABLE_SANDBOX=1
export ELECTRON_NO_SANDBOX=1
export DISABLE_SANDBOX=1
# Get the directory where this script is located
DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
# Launch electron with sandbox disabled
exec "\${DIR}/megacubo.original" --no-sandbox --disable-dev-shm-usage --disable-gpu-sandbox "$@"
`;
const wrapperPath = join(appOutDir, 'megacubo-wrapper');
writeFileSync(wrapperPath, wrapperScript, { mode: 0o755 }); // Make executable
// Replace the original executable with the wrapper
try {
renameSync(electronBinPath, electronBinPath + '.original');
renameSync(wrapperPath, electronBinPath);
console.log(' ✅ AppImage sandbox fix applied successfully');
console.log(' 📝 Original electron binary backed up as megacubo.original');
} catch (error) {
console.error(' ❌ Failed to apply sandbox fix:', error.message);
}
}
},
afterAllArtifactBuild: async (buildResult) => {
console.log('🎯 All artifacts built - fixing AppImage sandbox issues...');
// buildResult is a BuildResult object, artifactPaths is the array
const appImageArtifacts = buildResult.artifactPaths.filter(artifact =>
artifact.endsWith('.AppImage')
);
if (appImageArtifacts.length > 0) {
console.log(` 📦 Found ${appImageArtifacts.length} AppImage(s) to fix`);
for (const artifactPath of appImageArtifacts) {
console.log(` 🔧 Fixing sandbox in: ${artifactPath}`);
try {
// Make AppImage executable
execSync(`chmod +x "${artifactPath}"`, { stdio: 'inherit' });
// Create a temporary directory for extraction
const tempDir = `/tmp/appimage-fix-${Date.now()}`;
execSync(`mkdir -p "${tempDir}"`, { stdio: 'inherit' });
// Extract AppImage
execSync(`"${artifactPath}" --appimage-extract`, { cwd: tempDir, stdio: 'inherit' });
// Create wrapper script in extracted directory
const wrapperScript = `#!/bin/bash
# Fixed AppImage wrapper for sandbox issues
export ELECTRON_DISABLE_SANDBOX=1
export ELECTRON_NO_SANDBOX=1
export DISABLE_SANDBOX=1
exec "./AppRun" --no-sandbox --disable-dev-shm-usage --disable-gpu-sandbox "$@"
`;
writeFileSync(join(tempDir, 'squashfs-root', 'AppRun-fixed'), wrapperScript);
execSync(`chmod +x "${tempDir}/squashfs-root/AppRun-fixed"`, { stdio: 'inherit' });
// Backup original and replace
execSync(`mv "${tempDir}/squashfs-root/AppRun" "${tempDir}/squashfs-root/AppRun.original"`, { stdio: 'inherit' });
execSync(`cp "${tempDir}/squashfs-root/AppRun-fixed" "${tempDir}/squashfs-root/AppRun"`, { stdio: 'inherit' });
// Repack AppImage (need appimagetool)
try {
execSync(`which appimagetool`, { stdio: 'pipe' });
execSync(`appimagetool "${tempDir}/squashfs-root" "${artifactPath}.fixed"`, { stdio: 'inherit' });
execSync(`mv "${artifactPath}.fixed" "${artifactPath}"`, { stdio: 'inherit' });
console.log(` ✅ AppImage sandbox fixed with appimagetool: ${artifactPath}`);
} catch (appimagetoolError) {
// Fallback: try mksquashfs + elf binary modification
console.log(' ⚠️ appimagetool not found, trying alternative method...');
// Create new squashfs
execSync(`mksquashfs "${tempDir}/squashfs-root" "${tempDir}/appimage.squashfs" -comp xz -all-root`, { stdio: 'inherit' });
// This is complex - for now, just create a wrapper outside the AppImage
const externalWrapper = `#!/bin/bash
# External wrapper for AppImage sandbox fix
export ELECTRON_DISABLE_SANDBOX=1
export ELECTRON_NO_SANDBOX=1
export DISABLE_SANDBOX=1
exec "${artifactPath}" --no-sandbox --disable-dev-shm-usage --disable-gpu-sandbox "$@"
`;
const wrapperPath = `${artifactPath}.wrapper`;
writeFileSync(wrapperPath, externalWrapper);
execSync(`chmod +x "${wrapperPath}"`, { stdio: 'inherit' });
console.log(` ✅ Created external wrapper: ${wrapperPath}`);
console.log(` 📝 Use ./${artifactPath.split('/').pop()}.wrapper instead of ./${artifactPath.split('/').pop()}`);
}
// Cleanup
execSync(`rm -rf "${tempDir}"`, { stdio: 'inherit' });
} catch (error) {
console.error(` ❌ Failed to fix AppImage: ${error.message}`);
}
}
}
}
};