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.
- package/install-react-template.js +75 -27
- package/package.json +1 -1
|
@@ -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] 🛑
|
|
32
|
-
try { await ngrok.kill(); } catch
|
|
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.
|
|
104
|
+
console.log(\`\\n[Fleetbo] 🔗 React is ready. Initiating Tunnel...\`);
|
|
81
105
|
|
|
82
106
|
try {
|
|
83
|
-
|
|
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 (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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 <
|
|
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',
|
|
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, () => {});
|
|
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
|
-
|
|
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
|
|
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) {
|