create-fleetbo-project 1.2.43 → 1.2.45
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/install-react-template.js +89 -21
- package/package.json +1 -1
|
@@ -11,7 +11,9 @@ const branchName = 'master';
|
|
|
11
11
|
const archiveUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/${branchName}.tar.gz`;
|
|
12
12
|
const bootstrapUrl = 'https://us-central1-myapp-259bf.cloudfunctions.net/bootstrapProject';
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
// ------------------------------------------------------------------
|
|
15
|
+
// CONTENU DU CLI (Intégré pour génération automatique)
|
|
16
|
+
// ------------------------------------------------------------------
|
|
15
17
|
const CLI_SCRIPT_CONTENT = `#!/usr/bin/env node
|
|
16
18
|
const { spawn, execSync } = require('child_process');
|
|
17
19
|
const fs = require('fs');
|
|
@@ -73,9 +75,12 @@ const injectRouteIntoAppJs = (pageName, subPath = '') => {
|
|
|
73
75
|
|
|
74
76
|
if (!content.includes(alexRouteAnchor)) return false;
|
|
75
77
|
|
|
78
|
+
// Chemin dynamique selon si c'est une page ou un mock
|
|
76
79
|
const pathPrefix = subPath ? \`\${subPath}/\` : '';
|
|
77
80
|
const importLine = \`import \${pageName} from './pages/\${pathPrefix}\${pageName}';\`;
|
|
78
|
-
|
|
81
|
+
|
|
82
|
+
// CORRECTION ICI : Syntax React Router valide element={<PageName />}
|
|
83
|
+
const routeLine = \`<Route path="/\${pathPrefix.toLowerCase()}\${pageName.toLowerCase()}" element={<\${pageName} />} />\`;
|
|
79
84
|
|
|
80
85
|
let injected = false;
|
|
81
86
|
if (!content.includes(importLine)) {
|
|
@@ -83,6 +88,7 @@ const injectRouteIntoAppJs = (pageName, subPath = '') => {
|
|
|
83
88
|
injected = true;
|
|
84
89
|
}
|
|
85
90
|
if (!content.includes(routeLine)) {
|
|
91
|
+
// Injection précise dans l'ancre Alex
|
|
86
92
|
content = content.replace(alexRouteAnchor, \`\${routeLine}\\n \${alexRouteAnchor}\`);
|
|
87
93
|
injected = true;
|
|
88
94
|
}
|
|
@@ -155,6 +161,7 @@ if (command === 'alex') {
|
|
|
155
161
|
writeFile('src/pages/mocks/', 'Quick.jsx', mockCode);
|
|
156
162
|
}
|
|
157
163
|
}
|
|
164
|
+
|
|
158
165
|
} catch (error) {
|
|
159
166
|
process.stdout.write('\\r' + ' '.repeat(50) + '\\r');
|
|
160
167
|
console.error('\\n\\x1b[31m❌ Alex Error:\\x1b[0m ' + (error.response?.data?.message || error.message));
|
|
@@ -163,29 +170,60 @@ if (command === 'alex') {
|
|
|
163
170
|
|
|
164
171
|
const startAlexSession = async () => {
|
|
165
172
|
process.stdout.write('\\x1b[33m🛡️ Alex is checking runtime state...\\x1b[0m\\r');
|
|
166
|
-
|
|
173
|
+
|
|
174
|
+
let attempts = 0;
|
|
175
|
+
const maxAttempts = 5;
|
|
176
|
+
let isReady = false;
|
|
177
|
+
|
|
167
178
|
while (attempts < maxAttempts && !isReady) {
|
|
168
179
|
try {
|
|
169
|
-
const validation = await axios.post(ALEX_ENGINE_URL, {
|
|
180
|
+
const validation = await axios.post(ALEX_ENGINE_URL, {
|
|
181
|
+
prompt: "ping", validateProject: true, checkNetwork: true
|
|
182
|
+
}, { headers: { 'x-project-id': projectId }, timeout: 5000 });
|
|
183
|
+
|
|
170
184
|
if (validation.data?.isRunning) { isReady = true; break; }
|
|
171
|
-
attempts++;
|
|
172
|
-
|
|
185
|
+
attempts++;
|
|
186
|
+
if (attempts < maxAttempts) await new Promise(r => setTimeout(r, 2000));
|
|
187
|
+
} catch (error) {
|
|
188
|
+
attempts++;
|
|
189
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
190
|
+
}
|
|
173
191
|
}
|
|
192
|
+
|
|
174
193
|
if (!isReady) {
|
|
175
194
|
console.error('\\n\\x1b[31m⚠️ ENGINE OFFLINE:\\x1b[0m Start Fleetbo runtime first: "npm run fleetbo" ');
|
|
176
195
|
process.exit(1);
|
|
177
196
|
}
|
|
178
|
-
|
|
197
|
+
|
|
198
|
+
process.stdout.write(' '.repeat(60) + '\\r');
|
|
199
|
+
|
|
179
200
|
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
|
|
201
|
+
console.log('\\x1b[32mAlex ❯\\x1b[0m Welcome! I am Alex, your architect. What are we building today?');
|
|
202
|
+
console.log('');
|
|
203
|
+
|
|
181
204
|
const userName = testerEmail ? testerEmail.split('@')[0] : 'Dev';
|
|
182
|
-
const rl = readline.createInterface({
|
|
205
|
+
const rl = readline.createInterface({
|
|
206
|
+
input: process.stdin,
|
|
207
|
+
output: process.stdout,
|
|
208
|
+
prompt: \`\\x1b[34m\${userName} ❯ \\x1b[0m\`
|
|
209
|
+
});
|
|
210
|
+
|
|
183
211
|
rl.prompt();
|
|
212
|
+
|
|
184
213
|
rl.on('line', async (line) => {
|
|
185
|
-
if (['exit', 'quit'].includes(line.trim().toLowerCase())) {
|
|
186
|
-
|
|
214
|
+
if (['exit', 'quit'].includes(line.trim().toLowerCase())) {
|
|
215
|
+
console.log('\\n\\x1b[90m👋 Alex session closed.\\x1b[0m');
|
|
216
|
+
rl.close();
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (line.trim()) {
|
|
220
|
+
await processAlexRequest(line.trim());
|
|
221
|
+
console.log('');
|
|
222
|
+
}
|
|
187
223
|
rl.prompt();
|
|
188
|
-
}).on('close', () => {
|
|
224
|
+
}).on('close', () => {
|
|
225
|
+
process.exit(0);
|
|
226
|
+
});
|
|
189
227
|
};
|
|
190
228
|
|
|
191
229
|
if (!initialPrompt || initialPrompt === '?') startAlexSession();
|
|
@@ -223,6 +261,7 @@ if (GENERATOR_COMMANDS.includes(command)) {
|
|
|
223
261
|
}
|
|
224
262
|
|
|
225
263
|
const NULL_DEV = process.platform === 'win32' ? '>nul 2>&1' : '2>/dev/null';
|
|
264
|
+
|
|
226
265
|
function killProcessOnPort(port) {
|
|
227
266
|
try {
|
|
228
267
|
if (process.platform !== 'win32') {
|
|
@@ -231,6 +270,7 @@ function killProcessOnPort(port) {
|
|
|
231
270
|
}
|
|
232
271
|
} catch (e) {}
|
|
233
272
|
}
|
|
273
|
+
|
|
234
274
|
function killNetworkService() {
|
|
235
275
|
try {
|
|
236
276
|
const cmd = process.platform === 'win32' ? 'taskkill /IM cloudflared.exe /F' : 'pkill cloudflared';
|
|
@@ -240,10 +280,15 @@ function killNetworkService() {
|
|
|
240
280
|
|
|
241
281
|
let isExiting = false;
|
|
242
282
|
async function cleanupAndExit(code = 0) {
|
|
243
|
-
if (isExiting) return;
|
|
283
|
+
if (isExiting) return;
|
|
284
|
+
isExiting = true;
|
|
244
285
|
console.log('\\n[Fleetbo] 🛑 Stopping environment...');
|
|
245
|
-
try {
|
|
246
|
-
|
|
286
|
+
try {
|
|
287
|
+
await axios.post(UPDATE_NETWORK_URL, { keyApp, networkUrl: '', tester: testerEmail });
|
|
288
|
+
} catch (e) {}
|
|
289
|
+
killNetworkService();
|
|
290
|
+
killProcessOnPort(PORT);
|
|
291
|
+
process.exit(code);
|
|
247
292
|
}
|
|
248
293
|
process.on('SIGINT', () => cleanupAndExit(0));
|
|
249
294
|
process.on('SIGTERM', () => cleanupAndExit(0));
|
|
@@ -251,27 +296,44 @@ process.on('SIGTERM', () => cleanupAndExit(0));
|
|
|
251
296
|
async function syncFirebase(keyApp, networkUrl, testerEmail) {
|
|
252
297
|
try {
|
|
253
298
|
await axios.post(UPDATE_NETWORK_URL, { keyApp, networkUrl, tester: testerEmail });
|
|
299
|
+
|
|
254
300
|
console.log(\`\\n\\x1b[32m[Fleetbo]\\x1b[0m -------------------------------------------------------------\`);
|
|
255
301
|
console.log('\\x1b[32m[Fleetbo] GO GO GO ! FLEETBO STUDIO IS READY \\x1b[0m');
|
|
256
302
|
console.log(\`\\x1b[32m[Fleetbo] Link: https://fleetbo.io/studio/\${keyApp}\\x1b[0m\`);
|
|
257
303
|
console.log('\\x1b[32m[Fleetbo] You can now start coding and previewing in Studio. 🚀\\x1b[0m');
|
|
258
304
|
console.log(\`\\x1b[32m[Fleetbo]\\x1b[0m -------------------------------------------------------------\`);
|
|
259
|
-
} catch (err) {
|
|
305
|
+
} catch (err) {
|
|
306
|
+
console.error(\`[Fleetbo] ❌ Sync Error: \${err.message}\`);
|
|
307
|
+
}
|
|
260
308
|
}
|
|
261
309
|
|
|
262
310
|
async function runDevEnvironment() {
|
|
263
311
|
console.log(\`[Fleetbo] 🛡️ Initializing Dev Environment...\`);
|
|
264
|
-
killNetworkService();
|
|
312
|
+
killNetworkService();
|
|
313
|
+
killProcessOnPort(PORT);
|
|
314
|
+
if (!testerEmail) { console.error('Error: REACT_APP_TESTER_EMAIL missing'); process.exit(1); }
|
|
315
|
+
|
|
265
316
|
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
266
|
-
const devServer = spawn(npmCmd, ['start'], {
|
|
267
|
-
|
|
317
|
+
const devServer = spawn(npmCmd, ['start'], {
|
|
318
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
319
|
+
shell: true,
|
|
320
|
+
env: { ...process.env, BROWSER: 'none', PORT: PORT.toString() }
|
|
321
|
+
});
|
|
322
|
+
devServer.stdout.pipe(process.stdout);
|
|
323
|
+
devServer.stderr.pipe(process.stderr);
|
|
324
|
+
|
|
268
325
|
let connectionStarted = false;
|
|
269
326
|
devServer.stdout.on('data', (data) => {
|
|
270
327
|
const output = data.toString();
|
|
271
328
|
if (!connectionStarted && (output.includes('Local:') || output.includes('Compiled successfully'))) {
|
|
272
329
|
connectionStarted = true;
|
|
330
|
+
|
|
273
331
|
console.log('\\n[Fleetbo] ---------------------------------------------------');
|
|
274
|
-
console.log(\`[Fleetbo] 🔗 Establishing Secure Uplink
|
|
332
|
+
console.log(\`[Fleetbo] 🔗 Establishing Secure Uplink...\`);
|
|
333
|
+
console.log(\`[Fleetbo] 🛑 DO NOT open the Fleetbo Studio yet. \`);
|
|
334
|
+
console.log(\`[Fleetbo] ⏳ Please wait green message...\`);
|
|
335
|
+
console.log('[Fleetbo] ---------------------------------------------------');
|
|
336
|
+
|
|
275
337
|
const npxCmd = process.platform === 'win32' ? 'npx.cmd' : 'npx';
|
|
276
338
|
const uplink = spawn(npxCmd, ['cloudflared', 'tunnel', '--url', \`http://localhost:\${PORT}\`], { shell: true });
|
|
277
339
|
uplink.stderr.on('data', (chunk) => {
|
|
@@ -281,7 +343,13 @@ async function runDevEnvironment() {
|
|
|
281
343
|
}
|
|
282
344
|
});
|
|
283
345
|
}
|
|
284
|
-
|
|
346
|
+
|
|
347
|
+
runDevEnvironment();
|
|
348
|
+
`;
|
|
349
|
+
|
|
350
|
+
// ------------------------------------------------------------------
|
|
351
|
+
// FIN CONTENU CLI
|
|
352
|
+
// ------------------------------------------------------------------
|
|
285
353
|
|
|
286
354
|
|
|
287
355
|
const args = process.argv.slice(2);
|