create-fleetbo-project 1.2.41 → 1.2.43

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.
@@ -34,7 +34,7 @@ const command = args[0];
34
34
  process.env.DOTENV_SILENT = 'true';
35
35
  const envPath = path.join(process.cwd(), '.env');
36
36
  if (!fs.existsSync(envPath)) {
37
- console.error('\\\\x1b[31m%s\\\\x1b[0m', '⌠Error: Configuration file (.env) not found.');
37
+ console.error('\\x1b[31m%s\\x1b[0m', ' Error: Configuration file (.env) not found.');
38
38
  process.exit(1);
39
39
  }
40
40
  dotenv.config({ path: envPath, quiet: true });
@@ -48,19 +48,19 @@ const checkGitSecurity = () => {
48
48
  const gitignorePath = path.join(process.cwd(), '.gitignore');
49
49
  if (fs.existsSync(gitDir)) {
50
50
  if (!fs.existsSync(gitignorePath)) {
51
- console.error('\\\\n\\\\x1b[31m🚨 SECURITY ALERT:\\\\x1b[0m .git detected but no .gitignore found.');
51
+ console.error('\\n\\x1b[31m🚨 SECURITY ALERT:\\x1b[0m .git detected but no .gitignore found.');
52
52
  process.exit(1);
53
53
  }
54
54
  const gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
55
55
  if (!gitignoreContent.includes('.env')) {
56
- console.error('\\\\n\\\\x1b[31m🚨 CRITICAL RISK:\\\\x1b[0m .env is NOT ignored by Git.');
56
+ console.error('\\n\\x1b[31m🚨 CRITICAL RISK:\\x1b[0m .env is NOT ignored by Git.');
57
57
  process.exit(1);
58
58
  }
59
59
  }
60
60
  };
61
61
 
62
62
  if (!projectId) {
63
- console.error('\\\\n⌠Error: Project ID missing in .env.\\\\n');
63
+ console.error('\\n❌ Error: Project ID missing in .env.\\n');
64
64
  process.exit(1);
65
65
  }
66
66
 
@@ -73,19 +73,17 @@ const injectRouteIntoAppJs = (pageName, subPath = '') => {
73
73
 
74
74
  if (!content.includes(alexRouteAnchor)) return false;
75
75
 
76
- // Chemin dynamique selon si c'est une page ou un mock
77
- const pathPrefix = subPath ? \`\\\${subPath}/\` : '';
78
- const importLine = \`import \\\${pageName} from './pages/\\\${pathPrefix}\\\${pageName}';\`;
79
- const routeLine = \`<Route path="/\\\${pathPrefix.toLowerCase()}\\\${pageName.toLowerCase()}" element=<\\\${\\\${pageName} />} />\`;
76
+ const pathPrefix = subPath ? \`\${subPath}/\` : '';
77
+ const importLine = \`import \${pageName} from './pages/\${pathPrefix}\${pageName}';\`;
78
+ const routeLine = \`<Route path="/\${pathPrefix.toLowerCase()}\${pageName.toLowerCase()}" element=<\${\${pageName} />} />\`;
80
79
 
81
80
  let injected = false;
82
81
  if (!content.includes(importLine)) {
83
- content = content.replace(importAnchor, \`\\\${importLine}\\\\n\\\${importAnchor}\`);
82
+ content = content.replace(importAnchor, \`\${importLine}\\n\${importAnchor}\`);
84
83
  injected = true;
85
84
  }
86
85
  if (!content.includes(routeLine)) {
87
- // Injection précise dans l'ancre Alex
88
- content = content.replace(alexRouteAnchor, \`\\\${routeLine}\\\\n \\\${alexRouteAnchor}\`);
86
+ content = content.replace(alexRouteAnchor, \`\${routeLine}\\n \${alexRouteAnchor}\`);
89
87
  injected = true;
90
88
  }
91
89
 
@@ -96,11 +94,11 @@ const injectRouteIntoAppJs = (pageName, subPath = '') => {
96
94
  const showEnergyTransfer = async () => {
97
95
  const width = 30;
98
96
  for (let i = 0; i <= width; i++) {
99
- const dots = "â–ˆ".repeat(i); const empty = "â–'".repeat(width - i);
100
- process.stdout.write(\`\\\\r \\\\x1b[32mâš¡ Alex Energy Sync:\\\\x1b[0m [\\\${dots}\\\${empty}] \\\${Math.round((i / width) * 100)}%\`);
97
+ const dots = "".repeat(i); const empty = "".repeat(width - i);
98
+ process.stdout.write(\`\\r \\x1b[32m Alex Energy Sync:\\x1b[0m [\${dots}\${empty}] \${Math.round((i / width) * 100)}%\`);
101
99
  await new Promise(r => setTimeout(r, 45));
102
100
  }
103
- process.stdout.write('\\\\n');
101
+ process.stdout.write('\\n');
104
102
  };
105
103
 
106
104
  if (command === 'alex') {
@@ -108,51 +106,43 @@ if (command === 'alex') {
108
106
  const initialPrompt = args.slice(1).join(' ');
109
107
 
110
108
  const processAlexRequest = async (prompt) => {
111
- process.stdout.write('\\\\x1b[33m🧠Alex is thinking...\\\\x1b[0m');
109
+ process.stdout.write('\\x1b[33m🧠 Alex is thinking...\\x1b[0m');
112
110
  try {
113
111
  const result = await axios.post(ALEX_ENGINE_URL, { prompt, projectType: 'android' }, {
114
112
  headers: { 'x-project-id': projectId }
115
113
  });
116
114
 
117
115
  const aiData = result.data;
118
- // 1. On efface "Alex is thinking..."
119
- process.stdout.write('\\\\r' + ' '.repeat(50) + '\\\\r');
116
+ process.stdout.write('\\r' + ' '.repeat(50) + '\\r');
120
117
 
121
- // --- 1. GESTION DU QUOTA (EN ROUGE) ---
122
118
  if (aiData.status === 'quota_exceeded') {
123
- console.log(\`\\\\n\\\\x1b[31mâ›" ENGINE OUT OF FUEL:\\\\x1b[0m \\\${aiData.message}\`);
119
+ console.log(\`\\n\\x1b[31m ENGINE OUT OF FUEL:\\x1b[0m \${aiData.message}\`);
124
120
  return;
125
121
  }
126
122
 
127
- // --- 2. AFFICHAGE DE LA RÉPONSE ---
128
123
  if (aiData.status === 'success' || aiData.status === 'message') {
129
- // ✅ AJOUT : Saut de ligne pour séparer de votre commande "username â¯"
130
124
  console.log('');
131
-
132
- // Alex répond en Vert
133
- console.log(\`\\\\x1b[32mAlex â¯\\\\x1b[0m \\\${aiData.message || "I'm ready."}\`);
125
+ console.log(\`\\x1b[32mAlex ❯\\x1b[0m \${aiData.message || "I'm ready."}\`);
134
126
 
135
- // Jauge d'énergie (Bleu/Vert/Rouge)
136
127
  if (aiData.remainingTokens !== undefined) {
137
128
  const remaining = aiData.remainingTokens;
138
129
  const limit = aiData.limit || 2500;
139
130
  const percent = Math.round((remaining / limit) * 100);
140
- const energyColor = percent > 30 ? '\\\\x1b[32m' : '\\\\x1b[31m';
141
- console.log(\`\\\\x1b[36mðŸ"Š Energy:\\\\x1b[0m \\\${energyColor}\\\${percent}%\\\\x1b[0m (\\\${remaining}/\\\${limit} tokens left)\`);
131
+ const energyColor = percent > 30 ? '\\x1b[32m' : '\\x1b[31m';
132
+ console.log(\`\\x1b[36m📊 Energy:\\x1b[0m \${energyColor}\${percent}%\\x1b[0m (\${remaining}/\${limit} tokens left)\`);
142
133
  }
143
134
  }
144
135
 
145
- // --- 4. TRAITEMENT DES FICHIERS (SI PRÉSENTS) ---
146
136
  if (aiData.status === 'success' && aiData.moduleData) {
147
137
  const { fileName, code, mockFileName, mockCode, moduleName } = aiData.moduleData;
148
- console.log(\` \\\\x1b[90mâš™ï¸ Architecting: \\\${moduleName}\\\\x1b[0m\`);
138
+ console.log(\` \\x1b[90m⚙️ Architecting: \${moduleName}\\x1b[0m\`);
149
139
 
150
140
  const writeFile = (dir, name, content) => {
151
141
  const fullPath = path.join(process.cwd(), dir);
152
142
  const filePath = path.join(fullPath, name);
153
143
  if (!fs.existsSync(fullPath)) fs.mkdirSync(fullPath, { recursive: true });
154
144
  fs.writeFileSync(filePath, content);
155
- console.log(\` ✅ \\\\x1b[32m[Written]\\\\x1b[0m \\\${dir}\\\${name}\`);
145
+ console.log(\` \\x1b[32m[Written]\\x1b[0m \${dir}\${name}\`);
156
146
  };
157
147
 
158
148
  if (code && fileName) {
@@ -165,77 +155,37 @@ if (command === 'alex') {
165
155
  writeFile('src/pages/mocks/', 'Quick.jsx', mockCode);
166
156
  }
167
157
  }
168
-
169
158
  } catch (error) {
170
- process.stdout.write('\\\\r' + ' '.repeat(50) + '\\\\r');
171
- console.error('\\\\n\\\\x1b[31m⌠Alex Error:\\\\x1b[0m ' + (error.response?.data?.message || error.message));
159
+ process.stdout.write('\\r' + ' '.repeat(50) + '\\r');
160
+ console.error('\\n\\x1b[31m Alex Error:\\x1b[0m ' + (error.response?.data?.message || error.message));
172
161
  }
173
162
  };
174
163
 
175
164
  const startAlexSession = async () => {
176
- process.stdout.write('\\\\x1b[33mðŸ›¡ï¸ Alex is checking runtime state...\\\\x1b[0m\\\\r');
177
-
178
- let attempts = 0;
179
- const maxAttempts = 5;
180
- let isReady = false;
181
-
165
+ process.stdout.write('\\x1b[33m🛡️ Alex is checking runtime state...\\x1b[0m\\r');
166
+ let attempts = 0; const maxAttempts = 5; let isReady = false;
182
167
  while (attempts < maxAttempts && !isReady) {
183
168
  try {
184
- const validation = await axios.post(ALEX_ENGINE_URL, {
185
- prompt: "ping", validateProject: true, checkNetwork: true
186
- }, { headers: { 'x-project-id': projectId }, timeout: 5000 });
187
-
169
+ const validation = await axios.post(ALEX_ENGINE_URL, { prompt: "ping", validateProject: true, checkNetwork: true }, { headers: { 'x-project-id': projectId }, timeout: 5000 });
188
170
  if (validation.data?.isRunning) { isReady = true; break; }
189
- attempts++;
190
- if (attempts < maxAttempts) await new Promise(r => setTimeout(r, 2000));
191
- } catch (error) {
192
- attempts++;
193
- await new Promise(r => setTimeout(r, 2000));
194
- }
171
+ attempts++; if (attempts < maxAttempts) await new Promise(r => setTimeout(r, 2000));
172
+ } catch (error) { attempts++; await new Promise(r => setTimeout(r, 2000)); }
195
173
  }
196
-
197
174
  if (!isReady) {
198
- console.error('\\\\n\\\\x1b[31mâš ï¸ ENGINE OFFLINE:\\\\x1b[0m Start Fleetbo runtime first: "npm run fleetbo" ');
175
+ console.error('\\n\\x1b[31m⚠️ ENGINE OFFLINE:\\x1b[0m Start Fleetbo runtime first: "npm run fleetbo" ');
199
176
  process.exit(1);
200
177
  }
201
-
202
- // --- INITIALISATION DE L'INTERFACE VISUELLE ---
203
- process.stdout.write(' '.repeat(60) + '\\\\r'); // Efface le status de validation
204
-
205
- // 1. Accueil Alex (Vert)
206
- console.log('\\\\n\\\\x1b[32m🤖 Alex is now online.\\\\x1b[0m');
207
- console.log('\\\\x1b[32mAlex â¯\\\\x1b[0m Welcome! I am Alex, your architect. What are we building today?');
208
-
209
- // 2. Premier saut de ligne pour l'esthétique
210
- console.log('');
211
-
212
- // 3. Configuration du prompt Développeur (Bleu)
178
+ process.stdout.write(' '.repeat(60) + '\\r');
179
+ console.log('\\n\\x1b[32m🤖 Alex is now online.\\x1b[0m');
180
+ console.log('\\x1b[32mAlex ❯\\x1b[0m Welcome! I am Alex, your architect. What are we building today?\\n');
213
181
  const userName = testerEmail ? testerEmail.split('@')[0] : 'Dev';
214
- const rl = readline.createInterface({
215
- input: process.stdin,
216
- output: process.stdout,
217
- prompt: \`\\\\x1b[34m\\\${userName} ⯠\\\\x1b[0m\`
218
- });
219
-
182
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: \`\\x1b[34m\${userName} ❯ \\x1b[0m\` });
220
183
  rl.prompt();
221
-
222
184
  rl.on('line', async (line) => {
223
- if (['exit', 'quit'].includes(line.trim().toLowerCase())) {
224
- console.log('\\\\n\\\\x1b[90mðŸ'‹ Alex session closed.\\\\x1b[0m');
225
- rl.close();
226
- return;
227
- }
228
-
229
- if (line.trim()) {
230
- await processAlexRequest(line.trim());
231
- // ✅ SAUT DE LIGNE après la réponse d'Alex
232
- console.log('');
233
- }
234
-
185
+ if (['exit', 'quit'].includes(line.trim().toLowerCase())) { console.log('\\n\\x1b[90m👋 Alex session closed.\\x1b[0m'); rl.close(); return; }
186
+ if (line.trim()) { await processAlexRequest(line.trim()); console.log(''); }
235
187
  rl.prompt();
236
- }).on('close', () => {
237
- process.exit(0);
238
- });
188
+ }).on('close', () => { process.exit(0); });
239
189
  };
240
190
 
241
191
  if (!initialPrompt || initialPrompt === '?') startAlexSession();
@@ -246,7 +196,7 @@ if (command === 'alex') {
246
196
  if (command === 'deploy') {
247
197
  checkGitSecurity();
248
198
  (async () => {
249
- console.log('\\\\n\\\\x1b[36mâš¡ FLEETBO CLOUD ENGINE\\\\x1b[0m');
199
+ console.log('\\n\\x1b[36m FLEETBO CLOUD ENGINE\\x1b[0m');
250
200
  try {
251
201
  execSync('npm run build', { stdio: 'inherit' });
252
202
  let buildDir = fs.existsSync(path.join(process.cwd(), 'dist')) ? 'dist' : 'build';
@@ -257,38 +207,30 @@ if (command === 'deploy') {
257
207
  archive.directory(path.join(process.cwd(), buildDir), false);
258
208
  archive.finalize();
259
209
  });
260
- console.log('\\\\nðŸ"¦ \\\\x1b[33mPreparing Neural Logic for Uplink...\\\\x1b[0m');
210
+ console.log('\\n📦 \\x1b[33mPreparing Neural Logic for Uplink...\\x1b[0m');
261
211
  await showEnergyTransfer();
262
212
  await axios.post(CLOUD_ENGINE_URL, zipBuffer, { headers: { 'Content-Type': 'application/zip', 'x-project-id': projectId } });
263
- console.log('\\\\n✅ \\\\x1b[1mDEPLOYMENT SUCCESSFUL\\\\x1b[0m | \\\\x1b[32mAlex â¯\\\\x1b[0m Runtime updated.');
213
+ console.log('\\n \\x1b[1mDEPLOYMENT SUCCESSFUL\\x1b[0m | \\x1b[32mAlex ❯\\x1b[0m Runtime updated.');
264
214
  } catch (error) { process.exit(1); }
265
215
  })();
266
216
  return;
267
217
  }
268
218
 
269
- // ==========================================
270
- // 2. COMMANDE: GENERATE (Original préservé)
271
- // ==========================================
272
219
  const GENERATOR_COMMANDS = ['page', 'g', 'generate', 'android', 'ios'];
273
220
  if (GENERATOR_COMMANDS.includes(command)) {
274
221
  try { require('./page.js'); } catch (e) { console.error(e.message); process.exit(1); }
275
222
  return;
276
223
  }
277
224
 
278
- // ==========================================
279
- // 3. COMMANDE: DEV / CLEANUP (Original préservé)
280
- // ==========================================
281
225
  const NULL_DEV = process.platform === 'win32' ? '>nul 2>&1' : '2>/dev/null';
282
-
283
226
  function killProcessOnPort(port) {
284
227
  try {
285
228
  if (process.platform !== 'win32') {
286
- const pid = execSync(\`lsof -ti:\\\${port} \\\${NULL_DEV}\`).toString().trim();
287
- if (pid) execSync(\`kill -9 \\\${pid.split('\\\\n').join(' ')} \\\${NULL_DEV}\`);
229
+ const pid = execSync(\`lsof -ti:\${port} \${NULL_DEV}\`).toString().trim();
230
+ if (pid) execSync(\`kill -9 \${pid.split('\\n').join(' ')} \${NULL_DEV}\`);
288
231
  }
289
232
  } catch (e) {}
290
233
  }
291
-
292
234
  function killNetworkService() {
293
235
  try {
294
236
  const cmd = process.platform === 'win32' ? 'taskkill /IM cloudflared.exe /F' : 'pkill cloudflared';
@@ -298,15 +240,10 @@ function killNetworkService() {
298
240
 
299
241
  let isExiting = false;
300
242
  async function cleanupAndExit(code = 0) {
301
- if (isExiting) return;
302
- isExiting = true;
303
- console.log('\\\\n[Fleetbo] ðŸ›' Stopping environment...');
304
- try {
305
- await axios.post(UPDATE_NETWORK_URL, { keyApp, networkUrl: '', tester: testerEmail });
306
- } catch (e) {}
307
- killNetworkService();
308
- killProcessOnPort(PORT);
309
- process.exit(code);
243
+ if (isExiting) return; isExiting = true;
244
+ console.log('\\n[Fleetbo] 🛑 Stopping environment...');
245
+ try { await axios.post(UPDATE_NETWORK_URL, { keyApp, networkUrl: '', tester: testerEmail }); } catch (e) {}
246
+ killNetworkService(); killProcessOnPort(PORT); process.exit(code);
310
247
  }
311
248
  process.on('SIGINT', () => cleanupAndExit(0));
312
249
  process.on('SIGTERM', () => cleanupAndExit(0));
@@ -314,56 +251,37 @@ process.on('SIGTERM', () => cleanupAndExit(0));
314
251
  async function syncFirebase(keyApp, networkUrl, testerEmail) {
315
252
  try {
316
253
  await axios.post(UPDATE_NETWORK_URL, { keyApp, networkUrl, tester: testerEmail });
317
-
318
- console.log(\`\\\\n\\\\x1b[32m[Fleetbo]\\\\x1b[0m -------------------------------------------------------------\`);
319
- console.log('\\\\x1b[32m[Fleetbo] GO GO GO ! FLEETBO STUDIO IS READY \\\\x1b[0m');
320
- console.log(\`\\\\x1b[32m[Fleetbo] Link: https://fleetbo.io/studio/\\\${keyApp}\\\\x1b[0m\`);
321
- console.log('\\\\x1b[32m[Fleetbo] You can now start coding and previewing in Studio. 🚀\\\\x1b[0m');
322
- console.log(\`\\\\x1b[32m[Fleetbo]\\\\x1b[0m -------------------------------------------------------------\`);
323
- } catch (err) {
324
- console.error(\`[Fleetbo] ⌠Sync Error: \\\${err.message}\`);
325
- }
254
+ console.log(\`\\n\\x1b[32m[Fleetbo]\\x1b[0m -------------------------------------------------------------\`);
255
+ console.log('\\x1b[32m[Fleetbo] GO GO GO ! FLEETBO STUDIO IS READY \\x1b[0m');
256
+ console.log(\`\\x1b[32m[Fleetbo] Link: https://fleetbo.io/studio/\${keyApp}\\x1b[0m\`);
257
+ console.log('\\x1b[32m[Fleetbo] You can now start coding and previewing in Studio. 🚀\\x1b[0m');
258
+ console.log(\`\\x1b[32m[Fleetbo]\\x1b[0m -------------------------------------------------------------\`);
259
+ } catch (err) { console.error(\`[Fleetbo] ❌ Sync Error: \${err.message}\`); }
326
260
  }
327
261
 
328
262
  async function runDevEnvironment() {
329
- console.log(\`[Fleetbo] ðŸ›¡ï¸ Initializing Dev Environment...\`);
330
- killNetworkService();
331
- killProcessOnPort(PORT);
332
- if (!testerEmail) { console.error('Error: REACT_APP_TESTER_EMAIL missing'); process.exit(1); }
333
-
263
+ console.log(\`[Fleetbo] 🛡️ Initializing Dev Environment...\`);
264
+ killNetworkService(); killProcessOnPort(PORT);
334
265
  const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
335
- const devServer = spawn(npmCmd, ['start'], {
336
- stdio: ['ignore', 'pipe', 'pipe'],
337
- shell: true,
338
- env: { ...process.env, BROWSER: 'none', PORT: PORT.toString() }
339
- });
340
- devServer.stdout.pipe(process.stdout);
341
- devServer.stderr.pipe(process.stderr);
342
-
266
+ const devServer = spawn(npmCmd, ['start'], { stdio: ['ignore', 'pipe', 'pipe'], shell: true, env: { ...process.env, BROWSER: 'none', PORT: PORT.toString() } });
267
+ devServer.stdout.pipe(process.stdout); devServer.stderr.pipe(process.stderr);
343
268
  let connectionStarted = false;
344
269
  devServer.stdout.on('data', (data) => {
345
270
  const output = data.toString();
346
271
  if (!connectionStarted && (output.includes('Local:') || output.includes('Compiled successfully'))) {
347
272
  connectionStarted = true;
348
-
349
- console.log('\\\\n[Fleetbo] ---------------------------------------------------');
350
- console.log(\`[Fleetbo] 🔗 Establishing Secure Uplink...\`);
351
- console.log(\`[Fleetbo] 🛑 DO NOT open the Fleetbo Studio yet. \`);
352
- console.log(\`[Fleetbo] ⏳ Please wait green message...\`);
353
- console.log('[Fleetbo] ---------------------------------------------------');
354
-
273
+ console.log('\\n[Fleetbo] ---------------------------------------------------');
274
+ console.log(\`[Fleetbo] 🔗 Establishing Secure Uplink...\\n[Fleetbo] 🛑 DO NOT open the Fleetbo Studio yet.\\n[Fleetbo] ⏳ Please wait green message...\\n[Fleetbo] ---------------------------------------------------\`);
355
275
  const npxCmd = process.platform === 'win32' ? 'npx.cmd' : 'npx';
356
- const uplink = spawn(npxCmd, ['cloudflared', 'tunnel', '--url', \`http://localhost:\\\${PORT}\`], { shell: true });
276
+ const uplink = spawn(npxCmd, ['cloudflared', 'tunnel', '--url', \`http://localhost:\${PORT}\`], { shell: true });
357
277
  uplink.stderr.on('data', (chunk) => {
358
- const match = chunk.toString().match(/https:\\\\/\\\\/[a-zA-Z0-9-]+\\\\.trycloudflare\\\\.com/);
278
+ const match = chunk.toString().match(/https:\\/\\/[a-zA-Z0-9-]+\\.trycloudflare\\.com/);
359
279
  if (match) syncFirebase(keyApp, match[0], testerEmail);
360
280
  });
361
281
  }
362
282
  });
363
283
  }
364
-
365
- runDevEnvironment();
366
- `;
284
+ runDevEnvironment();`.replace(/`/g, '\\`').replace(/\${/g, '\\${');
367
285
 
368
286
 
369
287
  const args = process.argv.slice(2);
@@ -375,7 +293,7 @@ const bootstrapTokenArg = tokenArg ? tokenArg.split('=')[1] : null;
375
293
  const userEmailArg = emailArg ? emailArg.split('=')[1] : null;
376
294
 
377
295
  if (!projectNameArg || !bootstrapTokenArg || !userEmailArg) {
378
- console.error('\n Usage: npx create-fleetbo-project <name> --token=<token> --email=<email>');
296
+ console.error('\n Usage: npx create-fleetbo-project <name> --token=<token> --email=<email>');
379
297
  process.exit(1);
380
298
  }
381
299
 
@@ -429,17 +347,17 @@ function downloadEngine(url, dest) {
429
347
  }
430
348
 
431
349
  async function setupProject() {
432
- console.log(`\nâš¡ Initializing Fleetbo Framework for "${projectName}"...`);
350
+ console.log(`\n Initializing Fleetbo Framework for "${projectName}"...`);
433
351
 
434
352
  try {
435
353
  if (fs.existsSync(projectDir)) throw new Error(`Directory "${projectName}" already exists.`);
436
354
  fs.mkdirSync(projectDir);
437
355
 
438
- console.log(' [1/6]---------- Downloading Fleetbo Core Engine...');
356
+ console.log(' [1/7] 📥 Downloading Fleetbo Core Engine...');
439
357
  const archivePath = path.join(projectDir, 'engine.tar.gz');
440
358
  await downloadEngine(archiveUrl, archivePath);
441
359
 
442
- console.log(' [2/6]---------- Scaffolding project structure...');
360
+ console.log(' [2/7] 📦 Scaffolding project structure...');
443
361
  try {
444
362
  execSync(`tar -xf "${archivePath}" -C "${projectDir}" --strip-components=1`, { stdio: 'ignore' });
445
363
  fs.unlinkSync(archivePath);
@@ -447,22 +365,23 @@ async function setupProject() {
447
365
 
448
366
  process.chdir(projectDir);
449
367
 
450
- console.log(' [3/6]---------- Authenticating with Fleetbo Cloud...');
368
+ console.log(' [3/7] 🔑 Authenticating with Fleetbo Cloud...');
451
369
  const keys = await fetchProjectKeys(bootstrapTokenArg);
452
370
  if (!keys.enterpriseId) throw new Error("Invalid keys.");
453
371
 
454
- console.log(' [4.1/6]---------- Configuring environment & CLI...');
372
+ console.log(' [4/7] ⚙️ Configuring environment & CLI...');
455
373
 
374
+ // Correction indentation .env
456
375
  const envContent = `REACT_APP_FLEETBO_DB_KEY=${keys.fleetboDBKey}
457
- REACT_APP_ENTERPRISE_ID=${keys.enterpriseId}
458
- REACT_KEY_APP=${projectName}
459
- REACT_APP_TESTER_EMAIL=${userEmailArg}
460
- DANGEROUSLY_DISABLE_HOST_CHECK=true
461
- WDS_SOCKET_PORT=0`;
376
+ REACT_APP_ENTERPRISE_ID=${keys.enterpriseId}
377
+ REACT_KEY_APP=${projectName}
378
+ REACT_APP_TESTER_EMAIL=${userEmailArg}
379
+ DANGEROUSLY_DISABLE_HOST_CHECK=true
380
+ WDS_SOCKET_PORT=0`;
462
381
 
463
382
  fs.writeFileSync(path.join(projectDir, '.env'), envContent, 'utf8');
464
383
 
465
- console.log(' [4.2/6]---------- Securing environment (adding .gitignore)...');
384
+ console.log(' [5/7] 🛡️ Securing environment (adding .gitignore)...');
466
385
  const gitignoreContent = `# Fleetbo Security\n.env\n.env.local\nnode_modules/\ndist/\nbuild/\n.DS_Store\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n`;
467
386
  fs.writeFileSync(path.join(projectDir, '.gitignore'), gitignoreContent, 'utf8');
468
387
 
@@ -471,22 +390,22 @@ WDS_SOCKET_PORT=0`;
471
390
  fs.writeFileSync(path.join(scriptsDir, 'cli.js'), CLI_SCRIPT_CONTENT, 'utf8');
472
391
  try { fs.chmodSync(path.join(scriptsDir, 'cli.js'), '755'); } catch (e) {}
473
392
 
474
- console.log(' [5/6]---------- Installing dependencies...');
393
+ console.log(' [6/7] 📚 Installing dependencies...');
475
394
  execSync('npm install', { stdio: 'inherit' });
476
395
  execSync('npm install cloudflared dotenv axios archiver --save-dev', { stdio: 'ignore' });
477
396
 
478
- console.log(' [6/6]---------- Finalizing setup...');
397
+ console.log(' [7/7] Finalizing setup...');
479
398
  const packageJsonPath = path.join(projectDir, 'package.json');
480
399
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
481
400
  packageJson.name = projectName;
482
401
  packageJson.scripts = { ...packageJson.scripts, "fleetbo": "node scripts/cli.js", "dev": "node scripts/cli.js" };
483
402
  fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8');
484
403
 
485
- console.log('\n [Fleetbo] Project successfully created!');
486
- console.log(`\nðŸ'‰ Run: cd ${projectName} && npm run fleetbo`);
404
+ console.log('\n [Fleetbo] Project successfully created!');
405
+ console.log(`\n👉 Run: cd ${projectName} && npm run fleetbo`);
487
406
 
488
407
  } catch (error) {
489
- console.error('\n⌠Setup failed:', error.message);
408
+ console.error('\n❌ Setup failed:', error.message);
490
409
  if (fs.existsSync(projectDir)) try { fs.rmSync(projectDir, { recursive: true, force: true }); } catch(e){}
491
410
  process.exit(1);
492
411
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fleetbo-project",
3
- "version": "1.2.41",
3
+ "version": "1.2.43",
4
4
  "description": "Creates a new Fleetbo project.",
5
5
  "main": "install-react-template.js",
6
6
  "bin": {