create-fleetbo-project 1.2.13 → 1.2.14

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.
@@ -9,14 +9,13 @@ const https = require('https');
9
9
  const repoOwner = 'FleetFleetbo';
10
10
  const repoName = 'dev.fleetbo.io';
11
11
  const branchName = 'master';
12
- // URL de l'archive (On cible 'codeload' implicitement via GitHub)
13
12
  const archiveUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/${branchName}.tar.gz`;
14
13
  const bootstrapUrl = 'https://us-central1-myapp-259bf.cloudfunctions.net/bootstrapProject';
15
14
 
16
- // --- LE CONTENU DU GARDIEN (CLI.JS) ---
15
+ // --- LE CONTENU DU GARDIEN (CLI.JS) - VERSION BLINDÉE ---
17
16
  const CLI_SCRIPT_CONTENT = `#!/usr/bin/env node
18
17
 
19
- const { spawn } = require('child_process');
18
+ const { spawn, exec } = require('child_process');
20
19
  const fs = require('fs');
21
20
  const path = require('path');
22
21
  const axios = require('axios');
@@ -27,9 +26,19 @@ const os = require('os');
27
26
  const UPDATE_NETWORK_URL = 'https://us-central1-myapp-259bf.cloudfunctions.net/updateDeveloperNetwork';
28
27
  const PORT = 3000;
29
28
 
29
+ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
30
+
31
+ // 1. NETTOYAGE VIOLENT (Anti-Zombie)
32
+ async function forceKillNgrok() {
33
+ return new Promise((resolve) => {
34
+ const cmd = process.platform === 'win32' ? 'taskkill /IM ngrok.exe /F' : 'pkill ngrok';
35
+ exec(cmd, () => resolve());
36
+ });
37
+ }
38
+
30
39
  async function cleanupAndExit(code = 0) {
31
- console.log('\\n[Fleetbo] 🛑 Shutting down services...');
32
- try { await ngrok.kill(); } catch (e) {}
40
+ console.log('\\n[Fleetbo] 🛑 Stopping React...');
41
+ try { await ngrok.kill(); } catch(e){}
33
42
  process.exit(code);
34
43
  }
35
44
 
@@ -51,6 +60,11 @@ async function syncFirebase(keyApp, networkUrl) {
51
60
  async function runGuardian() {
52
61
  console.log(\`[Fleetbo] 🛡️ Starting Fleetbo Guardian on \${os.platform()}...\`);
53
62
 
63
+ // 2. NETTOYAGE AU DÉMARRAGE
64
+ console.log(\`[Fleetbo] 🧹 Cleaning up...\`);
65
+ await forceKillNgrok();
66
+ await sleep(1000);
67
+
54
68
  const envPath = path.join(process.cwd(), '.env');
55
69
  if (!fs.existsSync(envPath)) {
56
70
  console.error('Error: .env file not found.');
@@ -59,6 +73,15 @@ async function runGuardian() {
59
73
  dotenv.config({ path: envPath });
60
74
 
61
75
  const keyApp = process.env.REACT_KEY_APP;
76
+ const authToken = process.env.NGROK_AUTHTOKEN;
77
+
78
+ // 3. AUTHENTIFICATION (Si token présent dans .env, sinon Global)
79
+ if (authToken) {
80
+ try {
81
+ await ngrok.authtoken(authToken);
82
+ await sleep(1000);
83
+ } catch (e) {}
84
+ }
62
85
 
63
86
  console.log(\`[Fleetbo] 📦 Booting React Server...\`);
64
87
  const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
@@ -75,23 +98,34 @@ async function runGuardian() {
75
98
 
76
99
  devServer.stdout.on('data', async (data) => {
77
100
  const output = data.toString();
101
+
78
102
  if (!tunnelStarted && (output.includes('Local:') || output.includes('Compiled successfully'))) {
79
103
  tunnelStarted = true;
80
- console.log(\`\\n[Fleetbo] 🔗 React is ready. Opening secure tunnel...\`);
104
+ console.log(\`\\n[Fleetbo] 🔗 React is ready. Initiating Tunnel...\`);
81
105
 
82
106
  try {
83
- const url = await ngrok.connect({ addr: PORT });
107
+ // 4. CONNEXION AVEC NOM UNIQUE (Évite les collisions)
108
+ const url = await ngrok.connect({
109
+ addr: PORT,
110
+ name: \`fleetbo_\${Date.now()}\` // <--- CRUCIAL
111
+ });
84
112
  await syncFirebase(keyApp, url);
85
- } catch (err) {
86
- console.error('\\n[Fleetbo] NGROK CONNECTION FAILED');
87
- if (err.message.includes('ERR_NGROK_4018') || err.message.includes('limited') || err.message.includes('authtoken')) {
88
- console.error('-------------------------------------------------------');
89
- console.error('⚠️ MISSING OR INVALID AUTH TOKEN');
90
- console.error(' Run this command once:');
91
- console.error(' npx ngrok config add-authtoken <YOUR_TOKEN>');
92
- console.error('-------------------------------------------------------');
113
+ } catch (firstErr) {
114
+ // 5. RETRY LOGIC
115
+ try {
116
+ await sleep(2000);
117
+ const urlRetry = await ngrok.connect({
118
+ addr: PORT,
119
+ name: \`fleetbo_retry_\${Date.now()}\`
120
+ });
121
+ await syncFirebase(keyApp, urlRetry);
122
+ } catch (finalErr) {
123
+ console.error('\\n[Fleetbo] ❌ NGROK ERROR');
124
+ console.error("Message:", finalErr.message);
125
+ if (finalErr.message.includes('ERR_NGROK_4018')) {
126
+ console.error("👉 Add NGROK_AUTHTOKEN=... to your .env file OR run 'npx ngrok config add-authtoken <TOKEN>'");
127
+ }
93
128
  }
94
- cleanupAndExit(1);
95
129
  }
96
130
  }
97
131
  });
@@ -103,11 +137,17 @@ runGuardian();
103
137
  // --- Analyse des Arguments ---
104
138
  const args = process.argv.slice(2);
105
139
  const projectNameArg = args.find(arg => !arg.startsWith('--'));
140
+
141
+ // Argument Token Fleetbo
106
142
  const tokenArg = args.find(arg => arg.startsWith('--token='));
107
143
  const bootstrapTokenArg = tokenArg ? tokenArg.split('=')[1] : null;
108
144
 
145
+ // --- NOUVEAU : Argument Token Ngrok (Optionnel) ---
146
+ const ngrokArg = args.find(arg => arg.startsWith('--ngrok='));
147
+ const ngrokTokenArg = ngrokArg ? ngrokArg.split('=')[1] : null;
148
+
109
149
  if (!projectNameArg || !bootstrapTokenArg) {
110
- console.error('\n ❌ Usage: npx create-fleetbo-project <project-name> --token=<your-token>');
150
+ console.error('\n ❌ Usage: npx create-fleetbo-project <name> --token=<fleetbo-token> [--ngrok=<ngrok-token>]');
111
151
  process.exit(1);
112
152
  }
113
153
 
@@ -144,40 +184,34 @@ function fetchProjectKeys(token) {
144
184
  });
145
185
  }
146
186
 
147
- // --- CORRECTION MAJEURE : Ajout du User-Agent pour éviter l'erreur 503 ---
148
187
  function downloadEngine(url, dest) {
149
188
  return new Promise((resolve, reject) => {
150
- // On parse l'URL pour pouvoir ajouter des headers
151
189
  const uri = new URL(url);
152
190
  const options = {
153
191
  hostname: uri.hostname,
154
192
  path: uri.pathname + uri.search,
155
193
  method: 'GET',
156
194
  headers: {
157
- 'User-Agent': 'Fleetbo-CLI-Installer', // CRITIQUE POUR GITHUB
195
+ 'User-Agent': 'Fleetbo-CLI-Installer',
158
196
  'Accept': '*/*'
159
197
  }
160
198
  };
161
199
 
162
200
  const request = https.get(options, (response) => {
163
- // Gestion Redirection (301/302)
164
201
  if (response.statusCode === 301 || response.statusCode === 302) {
165
202
  if (!response.headers.location) {
166
203
  reject(new Error("Redirect found but no location header"));
167
204
  return;
168
205
  }
169
- // Appel récursif avec la nouvelle URL
170
206
  downloadEngine(response.headers.location, dest).then(resolve).catch(reject);
171
207
  return;
172
208
  }
173
209
 
174
- // Vérification du statut
175
210
  if (response.statusCode !== 200) {
176
211
  reject(new Error(`Failed to download (Status: ${response.statusCode})`));
177
212
  return;
178
213
  }
179
214
 
180
- // Écriture du fichier
181
215
  const file = fs.createWriteStream(dest);
182
216
  response.pipe(file);
183
217
 
@@ -186,7 +220,7 @@ function downloadEngine(url, dest) {
186
220
  });
187
221
 
188
222
  file.on('error', (err) => {
189
- fs.unlink(dest, () => {}); // Supprimer le fichier incomplet
223
+ fs.unlink(dest, () => {});
190
224
  reject(err);
191
225
  });
192
226
  });
@@ -227,7 +261,21 @@ async function setupProject() {
227
261
 
228
262
  // 4. Environment & CLI Generation
229
263
  console.log(' [4/6] ⚙️ Configuring environment & CLI...');
230
- const envContent = `REACT_APP_FLEETBO_DB_KEY=${keys.fleetboDBKey}\nREACT_APP_ENTERPRISE_ID=${keys.enterpriseId}\nREACT_KEY_APP=${projectName}\nDANGEROUSLY_DISABLE_HOST_CHECK=true\n`;
264
+
265
+ // --- CRÉATION DU .ENV ---
266
+ let envContent = `REACT_APP_FLEETBO_DB_KEY=${keys.fleetboDBKey}\n`;
267
+ envContent += `REACT_APP_ENTERPRISE_ID=${keys.enterpriseId}\n`;
268
+ envContent += `REACT_KEY_APP=${projectName}\n`;
269
+ envContent += `DANGEROUSLY_DISABLE_HOST_CHECK=true\n`;
270
+
271
+ // Ajout conditionnel du token Ngrok
272
+ if (ngrokTokenArg) {
273
+ console.log(' ✅ Ngrok token injected into .env');
274
+ envContent += `NGROK_AUTHTOKEN=${ngrokTokenArg}\n`;
275
+ } else {
276
+ console.log(' ℹ️ No Ngrok token provided. Assuming global config.');
277
+ }
278
+
231
279
  fs.writeFileSync(path.join(projectDir, '.env'), envContent, 'utf8');
232
280
  fs.writeFileSync(path.join(projectDir, 'cli.js'), CLI_SCRIPT_CONTENT, 'utf8');
233
281
 
@@ -244,7 +292,7 @@ async function setupProject() {
244
292
  packageJson.scripts = { ...packageJson.scripts, "fleetbo": "node cli.js", "dev": "node cli.js" };
245
293
  fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8');
246
294
 
247
- console.log('\n [Fleetbo] Project successfully created!');
295
+ console.log('\n [Fleetbo] Project successfully created!');
248
296
  console.log(`\n👉 Run: cd ${projectName} && npm run fleetbo`);
249
297
 
250
298
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fleetbo-project",
3
- "version": "1.2.13",
3
+ "version": "1.2.14",
4
4
  "description": "Creates a new Fleetbo project.",
5
5
  "main": "install-react-template.js",
6
6
  "bin": {