fleetbo-cockpit-cli 1.0.9 → 1.0.11

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 (2) hide show
  1. package/cli.js +53 -67
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -318,57 +318,72 @@ if (command === 'alex') {
318
318
  // COMMAND: android / ios (PROPULSION BUILD)
319
319
  // ============================================
320
320
  else if (command === 'android' || command === 'ios') {
321
- checkGitSecurity();
322
- const platform = command;
323
- const nativeDir = platform === 'android' ? 'public/native/android/' : 'public/native/ios/';
324
- const extension = platform === 'android' ? '.kt' : '.swift';
325
- const nativePath = path.join(process.cwd(), nativeDir);
326
-
327
- // Vérification des modules natifs
328
- let hasNativeFiles = false;
329
- let nativeFileCount = 0;
330
- if (fs.existsSync(nativePath)) {
331
- const files = fs.readdirSync(nativePath);
332
- const nativeFiles = files.filter(file => file.endsWith(extension));
333
- hasNativeFiles = nativeFiles.length > 0;
334
- nativeFileCount = nativeFiles.length;
335
- }
336
-
337
- if (!hasNativeFiles) {
338
- console.log(`\n\x1b[31m⚠️ ENGINE INCOMPLETE:\x1b[0m No native blueprints detected for \x1b[1m${platform.toUpperCase()}\x1b[0m.`);
339
- console.log(`\x1b[90mAlex must architect at least one ${extension} module before deployment.\x1b[0m`);
340
- console.log(`\x1b[90mRun: npm run fleetbo alex\x1b[0m\n`);
341
- process.exit(1);
342
- }
343
-
344
- const targetUrl = platform === 'android' ? ANDROID_BUILD_URL : IOS_BUILD_URL;
345
-
321
+
322
+ // 🟢 DÉBUT DE LA PROTECTION (Fonction Async Immédiate)
323
+ // Cela garantit que le code fonctionne partout, même via 'require()'
346
324
  (async () => {
325
+
326
+ // 🛑 INTERCEPTION IOS : BLOQUAGE NET (MAINTENANCE/BETA)
327
+ if (command === 'ios') {
328
+ console.log(`\n\x1b[36m⚡ FLEETBO IOS PROPULSION\x1b[0m`);
329
+ console.log(`\x1b[33m[0/3] Initializing Neural Uplink...\x1b[0m`);
330
+
331
+ // ✅ Ce 'await' est maintenant sécurisé
332
+ await new Promise(r => setTimeout(r, 800));
333
+
334
+ console.log(`\n\x1b[31m⛔ PROPULSION ABORTED: iOS Frequency Restricted.\x1b[0m`);
335
+ console.log(`\x1b[90m This module is currently reserved for Vanguard Pilots (Closed Beta).\x1b[0m`);
336
+ console.log(`\x1b[90m Please engage propulsion on Android frequency for now.\x1b[0m\n`);
337
+
338
+ process.exit(1);
339
+ }
340
+
341
+ checkGitSecurity();
342
+ const platform = command;
343
+ const nativeDir = platform === 'android' ? 'public/native/android/' : 'public/native/ios/';
344
+ const extension = platform === 'android' ? '.kt' : '.swift';
345
+ const nativePath = path.join(process.cwd(), nativeDir);
346
+
347
+ // Vérification des modules natifs
348
+ let hasNativeFiles = false;
349
+ let nativeFileCount = 0;
350
+ if (fs.existsSync(nativePath)) {
351
+ const files = fs.readdirSync(nativePath);
352
+ const nativeFiles = files.filter(file => file.endsWith(extension));
353
+ hasNativeFiles = nativeFiles.length > 0;
354
+ nativeFileCount = nativeFiles.length;
355
+ }
356
+
357
+ if (!hasNativeFiles) {
358
+ console.log(`\n\x1b[31m⚠️ ENGINE INCOMPLETE:\x1b[0m No native blueprints detected for \x1b[1m${platform.toUpperCase()}\x1b[0m.`);
359
+ console.log(`\x1b[90mAlex must architect at least one ${extension} module before deployment.\x1b[0m`);
360
+ console.log(`\x1b[90mRun: npm run fleetbo alex\x1b[0m\n`);
361
+ process.exit(1);
362
+ }
363
+
364
+ const targetUrl = platform === 'android' ? ANDROID_BUILD_URL : IOS_BUILD_URL;
365
+
347
366
  console.log(`\n\x1b[36m⚡ FLEETBO ${platform.toUpperCase()} PROPULSION\x1b[0m`);
348
367
  console.log(`\x1b[90m ${nativeFileCount} native module(s) detected\x1b[0m\n`);
349
368
 
350
369
  try {
351
370
  // ==========================================================
352
- // 🟢 NOUVEAU : ÉTAPE 0 (PRE-FLIGHT CHECK QUOTAS)
371
+ // PRE-FLIGHT CHECK QUOTAS
353
372
  // ==========================================================
354
373
  process.stdout.write(`\x1b[33m[0/3]\x1b[0m Checking Propulsion Quotas... `);
355
374
  try {
356
375
  await axios.post(targetUrl, {}, {
357
376
  headers: {
358
377
  'x-project-id': projectId,
359
- 'x-preflight': 'true' // Signale au serveur de ne pas chercher de ZIP
378
+ 'x-preflight': 'true'
360
379
  }
361
380
  });
362
381
  process.stdout.write(`\x1b[32mOK\x1b[0m\n\n`);
363
382
  } catch (preflightError) {
364
383
  process.stdout.write(`\x1b[31mDENIED\x1b[0m\n`);
365
-
366
- // 🟢 AJOUT CRITIQUE : On capture le message d'erreur du Cloud (JSON)
367
384
  if (preflightError.response && preflightError.response.data && preflightError.response.data.error) {
368
- // On remplace l'erreur technique Axios par le message métier clair
369
385
  throw new Error(preflightError.response.data.error);
370
386
  }
371
- // Fait sauter le code directement au "catch" global du bas sans jamais builder
372
387
  throw preflightError;
373
388
  }
374
389
 
@@ -376,7 +391,6 @@ else if (command === 'android' || command === 'ios') {
376
391
  console.log(`\x1b[33m[1/3]\x1b[0m Building React bundle...`);
377
392
  execSync('npm run build', { stdio: 'inherit' });
378
393
 
379
- // Déterminer le dossier de build
380
394
  let buildDir = fs.existsSync(path.join(process.cwd(), 'dist')) ? 'dist' : 'build';
381
395
  const buildPath = path.join(process.cwd(), buildDir);
382
396
 
@@ -384,7 +398,7 @@ else if (command === 'android' || command === 'ios') {
384
398
  throw new Error(`Build directory not found: ${buildDir}`);
385
399
  }
386
400
 
387
- // Étape 2: Créer le ZIP avec le bundle ET les modules natifs
401
+ // Étape 2: Créer le ZIP
388
402
  console.log(`\n\x1b[33m[2/3]\x1b[0m Packaging bundle + native modules...`);
389
403
 
390
404
  const zipBuffer = await new Promise((resolve, reject) => {
@@ -398,41 +412,20 @@ else if (command === 'android' || command === 'ios') {
398
412
  if (err.code !== 'ENOENT') reject(err);
399
413
  });
400
414
 
401
- // ============================================================
402
- // 📦 STRUCTURE DU ZIP (Compatible Fastfile + Cloud Function)
403
- // ============================================================
404
- // build.zip
405
- // └── build/
406
- // ├── index.html ← Pour assets/ (WebView)
407
- // ├── static/
408
- // └── native/
409
- // └── android/ ← Pour modules/ (.kt)
410
- // └── CameraModule.kt
411
- // ============================================================
412
-
413
- // 1. Ajouter le bundle React (dans build/)
414
415
  archive.directory(buildPath, 'build');
415
- console.log(` \x1b[32m✓\x1b[0m React bundle included`);
416
-
417
- // 2. Ajouter les modules natifs (dans build/native/android/ ou build/native/ios/)
418
- // Le Fastfile cherche: temp/build/native/android/*.kt
419
- // La Cloud Function cherche: native/android/*.kt (dans le ZIP)
420
416
  if (fs.existsSync(nativePath)) {
421
417
  archive.directory(nativePath, `build/native/${platform}`);
422
- console.log(` \x1b[32m✓\x1b[0m Native modules included (${nativeFileCount} files)`);
423
418
  }
424
-
425
419
  archive.finalize();
426
420
  });
427
421
 
428
422
  const sizeMB = (zipBuffer.length / 1024 / 1024).toFixed(2);
429
423
  console.log(` \x1b[32m✓\x1b[0m Bundle ready: ${sizeMB} MB`);
430
424
 
431
- // Étape 3: Upload vers Cloud Function
425
+ // Étape 3: Upload
432
426
  console.log(`\n\x1b[33m[3/3]\x1b[0m Uploading to Fleetbo OS...`);
433
427
  await showEnergyTransfer();
434
428
 
435
- // 🟢 ON UTILISE UNE VARIABLE LOCALE POUR LA RÉPONSE
436
429
  let uploadResponse;
437
430
  try {
438
431
  uploadResponse = await axios.post(targetUrl, zipBuffer, {
@@ -442,40 +435,33 @@ else if (command === 'android' || command === 'ios') {
442
435
  },
443
436
  maxContentLength: Infinity,
444
437
  maxBodyLength: Infinity,
445
- timeout: 120000 // 2 minutes timeout
438
+ timeout: 120000
446
439
  });
447
440
  } catch (axiosError) {
448
- // 🛑 SI AXIOS PLANTE (400, 403, 500), ON LANCE UNE ERREUR CLAIRE POUR LE CATCH GLOBAL
449
- // axiosError.response.data contient le JSON renvoyé par FandroidBuild
450
441
  if (axiosError.response && axiosError.response.data && axiosError.response.data.error) {
451
442
  throw new Error(axiosError.response.data.error);
452
443
  } else {
453
- // Timeout ou erreur réseau pure
454
444
  throw new Error(`Connection to OS failed: ${axiosError.message}`);
455
445
  }
456
446
  }
457
447
 
458
- // 🟢 SI AXIOS RÉUSSIT MAIS QUE LA RÉPONSE N'EST PAS UN SUCCÈS LOGIQUE
459
448
  if (uploadResponse.data && uploadResponse.data.success) {
460
449
  console.log(`\n\x1b[32m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m`);
461
450
  console.log(`\x1b[32m✓ ${platform.toUpperCase()} PROPULSION SUCCESSFUL\x1b[0m`);
462
451
  console.log(`\x1b[32m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m`);
463
452
  console.log(`\x1b[90m Deployment ID: ${uploadResponse.data.deploymentId || 'N/A'}\x1b[0m`);
464
- console.log(`\x1b[90m Your ${platform} bundle is now in the OS.\x1b[0m\n`);
453
+ console.log(`\x1b[90m ${uploadResponse.data.message || 'Complete.'}\x1b[0m\n`);
465
454
  } else {
466
- // Ce cas ne devrait pas arriver si le backend est bien codé (il renverrait une erreur HTTP), mais au cas où :
467
455
  throw new Error(uploadResponse.data?.error || 'Unknown logical error from Factory');
468
456
  }
469
457
 
470
- } catch (error) { // <-- LE CATCH GLOBAL (Reste inchangé)
458
+ } catch (error) {
471
459
  console.log(`\n\x1b[31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m`);
472
460
  console.log(`\x1b[31m✗ PROPULSION FAILED\x1b[0m`);
473
461
  console.log(`\x1b[31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m`);
474
462
 
475
- // L'erreur est maintenant propre, on l'affiche directement
476
463
  console.error(`\x1b[31m Error:\x1b[0m ${error.message}`);
477
464
 
478
- // Messages d'aide selon l'erreur
479
465
  if (error.message.includes('Limit') || error.message.includes('Quota')) {
480
466
  console.log(`\n\x1b[33m 💡 Tip:\x1b[0m Upgrade to Senior Pilot for more builds.`);
481
467
  } else if (error.message.includes('No native module')) {
@@ -483,11 +469,11 @@ else if (command === 'android' || command === 'ios') {
483
469
  } else if (error.message.includes('Trial Period Ended')) {
484
470
  console.log(`\n\x1b[33m 💡 Tip:\x1b[0m Your free sprint is over. Upgrade to Senior Pilot on fleetbo.io.`);
485
471
  }
486
-
487
472
  console.log('');
488
473
  process.exit(1);
489
474
  }
490
- })();
475
+
476
+ })(); // 🟢 FIN DE LA PROTECTION
491
477
  }
492
478
  // ============================================
493
479
  // COMMAND: page / g / generate
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetbo-cockpit-cli",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Fleetbo CLI - Build native mobile apps with React",
5
5
  "author": "Fleetbo",
6
6
  "license": "MIT",