metadidomi-builder 1.4.201125 → 1.6.2812251812

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.
Files changed (34) hide show
  1. package/README.md +1032 -572
  2. package/build_tools/backup-manager.js +3 -0
  3. package/build_tools/build_apk.js +3 -0
  4. package/build_tools/builder.js +2 -2
  5. package/build_tools/certs/cert-1a25871e.key +1 -0
  6. package/build_tools/certs/cert-1a25871e.pfx +0 -0
  7. package/build_tools/check-apk.js +211 -0
  8. package/build_tools/create-example-app.js +73 -0
  9. package/build_tools/decrypt_pfx_password.js +1 -26
  10. package/build_tools/diagnose-apk.js +61 -0
  11. package/build_tools/generate-icons.js +3 -0
  12. package/build_tools/generate-resources.js +3 -0
  13. package/build_tools/manage-dependencies.js +3 -0
  14. package/build_tools/process-dependencies.js +203 -0
  15. package/build_tools/resolve-transitive-deps.js +3 -0
  16. package/build_tools/restore-resources.js +3 -0
  17. package/build_tools/setup-androidx.js +131 -0
  18. package/build_tools/templates/bootstrap.template.js +27 -0
  19. package/build_tools/verify-apk-dependencies.js +261 -0
  20. package/build_tools_py/build_nsis_installer.py +1054 -19
  21. package/build_tools_py/builder.py +3 -3
  22. package/build_tools_py/compile_launcher_with_entry.py +19 -271
  23. package/build_tools_py/launcher_integration.py +19 -189
  24. package/build_tools_py/pyMetadidomi/README.md +98 -0
  25. package/build_tools_py/pyMetadidomi/__pycache__/pyMetadidomi.cpython-311.pyc +0 -0
  26. package/build_tools_py/pyMetadidomi/pyMetadidomi.py +16 -1675
  27. package/create-app.bat +31 -0
  28. package/create-app.ps1 +27 -0
  29. package/package.json +8 -2
  30. package/build_tools/certs/cert-65198130.key +0 -1
  31. package/build_tools/certs/cert-65198130.pfx +0 -0
  32. package/build_tools/certs/cert-f1fad9b5.key +0 -1
  33. package/build_tools/certs/cert-f1fad9b5.pfx +0 -0
  34. package/build_tools_py/pyMetadidomi/pyMetadidomi-obf.py +0 -19
@@ -0,0 +1,261 @@
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);