metadidomi-builder 1.6.2812251812 → 1.7.3101261533
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -774
- package/package.json +4 -6
- package/build_tools/backup-manager.js +0 -3
- package/build_tools/build_apk.js +0 -3
- package/build_tools/builder.js +0 -2
- package/build_tools/certs/cert-1a25871e.key +0 -1
- package/build_tools/certs/cert-1a25871e.pfx +0 -0
- package/build_tools/check-apk.js +0 -211
- package/build_tools/commands-help.js +0 -465
- package/build_tools/create-example-app.js +0 -73
- package/build_tools/decrypt_pfx_password.js +0 -1
- package/build_tools/diagnose-apk.js +0 -61
- package/build_tools/generate-icons.js +0 -3
- package/build_tools/generate-resources.js +0 -3
- package/build_tools/manage-dependencies.js +0 -3
- package/build_tools/process-dependencies.js +0 -203
- package/build_tools/prune_modules.js +0 -147
- package/build_tools/resolve-transitive-deps.js +0 -3
- package/build_tools/restore-resources.js +0 -3
- package/build_tools/setup-androidx.js +0 -131
- package/build_tools/signing.js +0 -20
- package/build_tools/templates/bootstrap.template.js +0 -105
- package/build_tools/templates/default.ico +0 -1
- package/build_tools/templates/nsis_template.nsi +0 -380
- package/build_tools/templates/security_addons.js +0 -60
- package/build_tools/templates/sfx_config.txt.tpl +0 -5
- package/build_tools/test_sign_with_vendor.js +0 -35
- package/build_tools/upx_advanced.js +0 -68
- package/build_tools/verify-apk-dependencies.js +0 -261
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
// (compression UPX automatisée + test d’exécution — re-sign si nécessaire)
|
|
2
|
-
// Usage: node build_tools/upx_advanced.js --exe=build/win-unpacked/electron.exe --reSign=true
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const { execSync } = require('child_process');
|
|
5
|
-
const argv = require('minimist')(process.argv.slice(2));
|
|
6
|
-
const exe = argv.exe;
|
|
7
|
-
if (!exe || !fs.existsSync(exe)) {
|
|
8
|
-
console.error('Provide valid --exe path to electron binary');
|
|
9
|
-
process.exit(1);
|
|
10
|
-
}
|
|
11
|
-
try {
|
|
12
|
-
// Vérifier que UPX est disponible
|
|
13
|
-
const upxPath = process.env.UPX_PATH;
|
|
14
|
-
if (!upxPath || !fs.existsSync(upxPath)) {
|
|
15
|
-
console.error('UPX non trouvé. Vérifiez que upx.exe est présent dans build_tools/vendor/upx/');
|
|
16
|
-
process.exit(1);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// Par défaut, on ne fait que --best --force (rapide). Pour --ultra-brute, il faut UPX_ULTRA_BRUTE=true
|
|
21
|
-
const ultraBrute = process.env.UPX_ULTRA_BRUTE === 'true';
|
|
22
|
-
const levels = ultraBrute ? ['--best --force', '--ultra-brute --force'] : ['--best --force'];
|
|
23
|
-
|
|
24
|
-
let compressed = false;
|
|
25
|
-
for (const level of levels) {
|
|
26
|
-
try {
|
|
27
|
-
console.log('Applying UPX with:', level);
|
|
28
|
-
execSync(`"${upxPath}" ${level} "${exe}"`, {
|
|
29
|
-
stdio: 'inherit',
|
|
30
|
-
timeout: ultraBrute ? 600000 : 60000 // 10 min max pour ultra-brute, 1 min sinon
|
|
31
|
-
});
|
|
32
|
-
compressed = true;
|
|
33
|
-
break; // Si réussi, on arrête là
|
|
34
|
-
} catch(e) {
|
|
35
|
-
console.warn('UPX pass failed for', level, '\n', e.message);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!compressed) {
|
|
40
|
-
console.warn('Aucun niveau de compression UPX n\'a réussi. L\'exécutable reste non compressé.');
|
|
41
|
-
process.exit(0); // Exit proprement sans erreur
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Test that exe still launches headless and exits quick
|
|
45
|
-
console.log('Testing exe launch (headless) — timeout 15s');
|
|
46
|
-
try {
|
|
47
|
-
execSync(`"${exe}" --version`, {
|
|
48
|
-
stdio: 'inherit',
|
|
49
|
-
timeout: 15000, // 15 secondes de timeout
|
|
50
|
-
windowsHide: true // Cache la fenêtre cmd
|
|
51
|
-
});
|
|
52
|
-
} catch (e) {
|
|
53
|
-
console.warn('Test de l\'exécutable échoué, mais on continue:', e.message);
|
|
54
|
-
}
|
|
55
|
-
console.log('UPX applied and binary test passed.');
|
|
56
|
-
|
|
57
|
-
// Optionally re-sign if SIGNING is configured
|
|
58
|
-
if (argv.reSign === 'true' && process.env.SIGNTOOL && process.env.PFX_PATH && process.env.PFX_PASS) {
|
|
59
|
-
console.log('Re-signing exe with signtool...');
|
|
60
|
-
const signCmd = `"${process.env.SIGNTOOL}" sign /f "${process.env.PFX_PATH}" /p "${process.env.PFX_PASS}" /tr http://timestamp.digicert.com /td sha256 /fd sha256 "${exe}"`;
|
|
61
|
-
execSync(signCmd, { stdio: 'inherit' });
|
|
62
|
-
console.log('Re-signed.');
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
} catch (err) {
|
|
66
|
-
console.error('UPX advanced error', err);
|
|
67
|
-
process.exit(1);
|
|
68
|
-
}
|
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const { execSync } = require('child_process');
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Vérificateur de dépendances dans l'APK final
|
|
9
|
-
* Extrait et analyse le classes.dex pour confirmer que toutes les classes sont présentes
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const projectDir = process.argv[2] || process.cwd();
|
|
13
|
-
const buildDir = path.join(projectDir, 'build');
|
|
14
|
-
const libsExtractedDir = path.join(buildDir, 'libs-extracted');
|
|
15
|
-
const configPath = path.join(projectDir, 'app-config.json');
|
|
16
|
-
|
|
17
|
-
console.log('🔍 Vérification des dépendances dans l\'APK\n');
|
|
18
|
-
|
|
19
|
-
// Trouver l'APK généré
|
|
20
|
-
const apkFiles = fs.readdirSync(projectDir).filter(f => f.endsWith('.apk'));
|
|
21
|
-
if (apkFiles.length === 0) {
|
|
22
|
-
console.error('❌ Aucun fichier APK trouvé dans le projet');
|
|
23
|
-
process.exit(1);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const apkPath = path.join(projectDir, apkFiles[0]);
|
|
27
|
-
console.log(`📦 APK cible: ${apkFiles[0]}`);
|
|
28
|
-
console.log(` Taille: ${(fs.statSync(apkPath).size / 1024 / 1024).toFixed(2)} MB\n`);
|
|
29
|
-
|
|
30
|
-
// Déterminer le chemin de 7za
|
|
31
|
-
function getSevenZipPath() {
|
|
32
|
-
const buildToolsDir = path.dirname(__filename);
|
|
33
|
-
const platform = process.platform;
|
|
34
|
-
const arch = process.arch;
|
|
35
|
-
|
|
36
|
-
if (platform === 'win32') {
|
|
37
|
-
const archDir = arch === 'x64' ? 'x64' : (arch === 'arm64' ? 'arm64' : 'ia32');
|
|
38
|
-
return path.join(buildToolsDir, 'vendor', '7zip-bin', 'win', archDir, '7za.exe');
|
|
39
|
-
} else if (platform === 'linux') {
|
|
40
|
-
return path.join(buildToolsDir, 'vendor', '7zip-bin', 'linux', 'x64', '7za');
|
|
41
|
-
} else if (platform === 'darwin') {
|
|
42
|
-
return path.join(buildToolsDir, 'vendor', '7zip-bin', 'mac', 'x64', '7za');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
throw new Error(`Plateforme non supportée: ${platform}`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const SEVENZIP = getSevenZipPath();
|
|
49
|
-
const SDK = path.join(path.dirname(__filename), 'vendor', 'android', 'android-sdk');
|
|
50
|
-
const AAPT2 = path.join(SDK, 'build-tools', '34.0.0', 'aapt2.exe');
|
|
51
|
-
|
|
52
|
-
// Charger app-config pour avoir la liste des dépendances attendues
|
|
53
|
-
let expectedDeps = [];
|
|
54
|
-
if (fs.existsSync(configPath)) {
|
|
55
|
-
try {
|
|
56
|
-
const appConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
57
|
-
if (appConfig.dependencies && appConfig.dependencies.androidx) {
|
|
58
|
-
expectedDeps = appConfig.dependencies.androidx.map(d => ({
|
|
59
|
-
name: d.name,
|
|
60
|
-
filename: path.basename(d.aar || d.name)
|
|
61
|
-
}));
|
|
62
|
-
}
|
|
63
|
-
} catch (e) {
|
|
64
|
-
console.warn('⚠️ Impossible de lire app-config.json:', e.message);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Extraire classes.dex depuis l'APK
|
|
69
|
-
const tempDir = path.join(buildDir, `temp_apk_verify_${Date.now()}`);
|
|
70
|
-
fs.mkdirSync(tempDir, { recursive: true });
|
|
71
|
-
|
|
72
|
-
console.log('📥 Extraction de classes.dex depuis l\'APK...\n');
|
|
73
|
-
|
|
74
|
-
try {
|
|
75
|
-
const extractCmd = `"${SEVENZIP}" x "${apkPath}" "classes.dex" -o"${tempDir}" -y`;
|
|
76
|
-
execSync(extractCmd, { stdio: 'pipe', shell: 'cmd.exe' });
|
|
77
|
-
} catch (e) {
|
|
78
|
-
console.error('❌ Impossible d\'extraire classes.dex');
|
|
79
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
80
|
-
process.exit(1);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const classesDexPath = path.join(tempDir, 'classes.dex');
|
|
84
|
-
if (!fs.existsSync(classesDexPath)) {
|
|
85
|
-
console.error('❌ classes.dex introuvable dans l\'APK');
|
|
86
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
87
|
-
process.exit(1);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const dexStats = fs.statSync(classesDexPath);
|
|
91
|
-
console.log(`✓ classes.dex extrait (${(dexStats.size / 1024).toFixed(2)} KB)\n`);
|
|
92
|
-
|
|
93
|
-
// Utiliser dexdump pour lister les classes dans le DEX
|
|
94
|
-
console.log('📋 Analyse des classes dans classes.dex...\n');
|
|
95
|
-
|
|
96
|
-
const dexdumpPath = path.join(SDK, 'build-tools', '34.0.0', 'dexdump.exe');
|
|
97
|
-
let dexClasses = [];
|
|
98
|
-
|
|
99
|
-
try {
|
|
100
|
-
const dumpCmd = `"${dexdumpPath}" "${classesDexPath}"`;
|
|
101
|
-
const output = execSync(dumpCmd, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
102
|
-
|
|
103
|
-
// Parser le output de dexdump pour extraire les noms de classes
|
|
104
|
-
// Format: Class descriptor : 'Lcom/example/Class;'
|
|
105
|
-
const classRegex = /Class descriptor\s*:\s*'([^']+)'/g;
|
|
106
|
-
let match;
|
|
107
|
-
while ((match = classRegex.exec(output)) !== null) {
|
|
108
|
-
const className = match[1].slice(1, -1).replace(/\//g, '.');
|
|
109
|
-
dexClasses.push(className);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
console.log(`✓ Trouvé ${dexClasses.length} classes dans classes.dex\n`);
|
|
113
|
-
} catch (e) {
|
|
114
|
-
console.warn('⚠️ Impossible d\'analyser classes.dex avec dexdump');
|
|
115
|
-
console.log(' Utilisation de l\'analyse alternative...\n');
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Analyser les JAR extraits pour compter les classes attendues
|
|
119
|
-
console.log('📊 Analyse des dépendances téléchargées...\n');
|
|
120
|
-
|
|
121
|
-
let expectedClasses = new Map();
|
|
122
|
-
let totalExpectedClasses = 0;
|
|
123
|
-
|
|
124
|
-
if (fs.existsSync(libsExtractedDir)) {
|
|
125
|
-
const extractedJars = fs.readdirSync(libsExtractedDir).filter(f => f.endsWith('.jar'));
|
|
126
|
-
|
|
127
|
-
console.log(`Fichiers JAR extraits: ${extractedJars.length}\n`);
|
|
128
|
-
|
|
129
|
-
for (const jarFile of extractedJars) {
|
|
130
|
-
const jarPath = path.join(libsExtractedDir, jarFile);
|
|
131
|
-
const jarTempDir = path.join(tempDir, `jar_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`);
|
|
132
|
-
fs.mkdirSync(jarTempDir, { recursive: true });
|
|
133
|
-
|
|
134
|
-
try {
|
|
135
|
-
// Lister le contenu du JAR
|
|
136
|
-
const listCmd = `"${SEVENZIP}" l "${jarPath}"`;
|
|
137
|
-
const jarContent = execSync(listCmd, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
138
|
-
|
|
139
|
-
// Compter les fichiers .class
|
|
140
|
-
const classFiles = (jarContent.match(/\.class$/gm) || []).length;
|
|
141
|
-
const packages = new Set();
|
|
142
|
-
|
|
143
|
-
const pkgRegex = /([a-zA-Z0-9/_-]+)\/[^/]+\.class$/gm;
|
|
144
|
-
let m;
|
|
145
|
-
while ((m = pkgRegex.exec(jarContent)) !== null) {
|
|
146
|
-
packages.add(m[1].replace(/\//g, '.'));
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (classFiles > 0) {
|
|
150
|
-
expectedClasses.set(jarFile, classFiles);
|
|
151
|
-
totalExpectedClasses += classFiles;
|
|
152
|
-
console.log(` 📦 ${jarFile}`);
|
|
153
|
-
console.log(` Classes: ${classFiles}`);
|
|
154
|
-
if (packages.size > 0 && packages.size <= 10) {
|
|
155
|
-
console.log(` Packages: ${Array.from(packages).slice(0, 5).join(', ')}${packages.size > 5 ? '...' : ''}`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
} catch (e) {
|
|
159
|
-
console.warn(` ⚠️ Erreur analyse ${jarFile}: ${e.message.substring(0, 50)}`);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Nettoyer
|
|
163
|
-
try {
|
|
164
|
-
fs.rmSync(jarTempDir, { recursive: true, force: true });
|
|
165
|
-
} catch (e) {}
|
|
166
|
-
}
|
|
167
|
-
} else {
|
|
168
|
-
console.log('⚠️ Aucun répertoire libs-extracted trouvé');
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Rapport de synthèse
|
|
172
|
-
console.log('\n' + '='.repeat(60));
|
|
173
|
-
console.log('📊 RAPPORT DE SYNTHÈSE');
|
|
174
|
-
console.log('='.repeat(60) + '\n');
|
|
175
|
-
|
|
176
|
-
console.log('✅ Classes présentes dans classes.dex:');
|
|
177
|
-
if (dexClasses.length > 0) {
|
|
178
|
-
console.log(` ${dexClasses.length} classes totales`);
|
|
179
|
-
|
|
180
|
-
// Grouper par package
|
|
181
|
-
const packageCounts = {};
|
|
182
|
-
for (const cls of dexClasses) {
|
|
183
|
-
const pkg = cls.substring(0, cls.lastIndexOf('.'));
|
|
184
|
-
packageCounts[pkg] = (packageCounts[pkg] || 0) + 1;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const sortedPkgs = Object.entries(packageCounts)
|
|
188
|
-
.sort((a, b) => b[1] - a[1])
|
|
189
|
-
.slice(0, 10);
|
|
190
|
-
|
|
191
|
-
console.log('\n Top 10 packages:');
|
|
192
|
-
for (const [pkg, count] of sortedPkgs) {
|
|
193
|
-
console.log(` - ${pkg}: ${count} classes`);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Vérifier les packages AndroidX essentiels
|
|
197
|
-
console.log('\n Vérification des packages essentiels:');
|
|
198
|
-
const essentialPackages = [
|
|
199
|
-
'androidx.appcompat',
|
|
200
|
-
'androidx.core',
|
|
201
|
-
'androidx.fragment',
|
|
202
|
-
'androidx.lifecycle',
|
|
203
|
-
'android.app',
|
|
204
|
-
'android.widget',
|
|
205
|
-
'com.google.android.material'
|
|
206
|
-
];
|
|
207
|
-
|
|
208
|
-
for (const pkg of essentialPackages) {
|
|
209
|
-
const found = Object.keys(packageCounts).filter(p => p.startsWith(pkg)).length > 0;
|
|
210
|
-
console.log(` ${found ? '✓' : '✗'} ${pkg}`);
|
|
211
|
-
}
|
|
212
|
-
} else {
|
|
213
|
-
console.log(' ⚠️ Impossible de lister les classes (dexdump non disponible)');
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
console.log('\n📦 Dépendances déclarées:');
|
|
217
|
-
if (expectedDeps.length > 0) {
|
|
218
|
-
console.log(` ${expectedDeps.length} dépendances `);
|
|
219
|
-
for (const dep of expectedDeps.slice(0, 10)) {
|
|
220
|
-
console.log(` - ${dep.name}`);
|
|
221
|
-
}
|
|
222
|
-
if (expectedDeps.length > 10) {
|
|
223
|
-
console.log(` ... et ${expectedDeps.length - 10} autres`);
|
|
224
|
-
}
|
|
225
|
-
} else {
|
|
226
|
-
console.log(' ℹ️ Aucune dépendance déclarée détectée');
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
console.log('\n📥 JAR extraits à compiler:');
|
|
230
|
-
if (expectedClasses.size > 0) {
|
|
231
|
-
console.log(` ${expectedClasses.size} fichiers JAR`);
|
|
232
|
-
console.log(` ${totalExpectedClasses} classes attendues au total`);
|
|
233
|
-
} else {
|
|
234
|
-
console.log(' ℹ️ Aucun JAR trouvé');
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Vérification finale
|
|
238
|
-
console.log('\n' + '='.repeat(60));
|
|
239
|
-
if (dexClasses.length > 0 && dexClasses.length > 100) {
|
|
240
|
-
console.log('✅ RÉSULTAT: Les dépendances semblent correctement incluses');
|
|
241
|
-
console.log(` (${dexClasses.length} classes détectées)`);
|
|
242
|
-
} else if (dexClasses.length > 0) {
|
|
243
|
-
console.log('⚠️ RÉSULTAT: Nombre limité de classes détecté');
|
|
244
|
-
console.log(` (${dexClasses.length} classes)`);
|
|
245
|
-
console.log(' Vérifiez que la compilation D8 a inclus tous les JAR');
|
|
246
|
-
} else {
|
|
247
|
-
console.log('❌ RÉSULTAT: Impossible de vérifier les classes');
|
|
248
|
-
console.log(' Utilisez dexdump manuellement: dexdump classes.dex');
|
|
249
|
-
}
|
|
250
|
-
console.log('='.repeat(60) + '\n');
|
|
251
|
-
|
|
252
|
-
// Nettoyer
|
|
253
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
254
|
-
|
|
255
|
-
// Commandes de vérification manuelle
|
|
256
|
-
console.log('💡 Pour une vérification manuelle:');
|
|
257
|
-
console.log(` 1. Extraire classes.dex: 7z x ${apkFiles[0]} classes.dex`);
|
|
258
|
-
console.log(` 2. Lister les classes: dexdump classes.dex | grep "Class descriptor"`);
|
|
259
|
-
console.log(` 3. Ou utiliser: strings classes.dex | grep "^Landroidx/" | sort\n`);
|
|
260
|
-
|
|
261
|
-
process.exit(0);
|