create-fleetbo-project 1.2.12 → 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 +120 -26
- package/package.json +1 -1
|
@@ -12,10 +12,10 @@ const branchName = 'master';
|
|
|
12
12
|
const archiveUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/${branchName}.tar.gz`;
|
|
13
13
|
const bootstrapUrl = 'https://us-central1-myapp-259bf.cloudfunctions.net/bootstrapProject';
|
|
14
14
|
|
|
15
|
-
// --- LE CONTENU DU GARDIEN (
|
|
15
|
+
// --- LE CONTENU DU GARDIEN (CLI.JS) - VERSION BLINDÉE ---
|
|
16
16
|
const CLI_SCRIPT_CONTENT = `#!/usr/bin/env node
|
|
17
17
|
|
|
18
|
-
const { spawn } = require('child_process');
|
|
18
|
+
const { spawn, exec } = require('child_process');
|
|
19
19
|
const fs = require('fs');
|
|
20
20
|
const path = require('path');
|
|
21
21
|
const axios = require('axios');
|
|
@@ -26,9 +26,19 @@ const os = require('os');
|
|
|
26
26
|
const UPDATE_NETWORK_URL = 'https://us-central1-myapp-259bf.cloudfunctions.net/updateDeveloperNetwork';
|
|
27
27
|
const PORT = 3000;
|
|
28
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
|
+
|
|
29
39
|
async function cleanupAndExit(code = 0) {
|
|
30
|
-
console.log('\\n[Fleetbo] 🛑
|
|
31
|
-
try { await ngrok.kill(); } catch
|
|
40
|
+
console.log('\\n[Fleetbo] 🛑 Stopping React...');
|
|
41
|
+
try { await ngrok.kill(); } catch(e){}
|
|
32
42
|
process.exit(code);
|
|
33
43
|
}
|
|
34
44
|
|
|
@@ -50,6 +60,11 @@ async function syncFirebase(keyApp, networkUrl) {
|
|
|
50
60
|
async function runGuardian() {
|
|
51
61
|
console.log(\`[Fleetbo] 🛡️ Starting Fleetbo Guardian on \${os.platform()}...\`);
|
|
52
62
|
|
|
63
|
+
// 2. NETTOYAGE AU DÉMARRAGE
|
|
64
|
+
console.log(\`[Fleetbo] 🧹 Cleaning up...\`);
|
|
65
|
+
await forceKillNgrok();
|
|
66
|
+
await sleep(1000);
|
|
67
|
+
|
|
53
68
|
const envPath = path.join(process.cwd(), '.env');
|
|
54
69
|
if (!fs.existsSync(envPath)) {
|
|
55
70
|
console.error('Error: .env file not found.');
|
|
@@ -58,6 +73,15 @@ async function runGuardian() {
|
|
|
58
73
|
dotenv.config({ path: envPath });
|
|
59
74
|
|
|
60
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
|
+
}
|
|
61
85
|
|
|
62
86
|
console.log(\`[Fleetbo] 📦 Booting React Server...\`);
|
|
63
87
|
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
@@ -74,23 +98,34 @@ async function runGuardian() {
|
|
|
74
98
|
|
|
75
99
|
devServer.stdout.on('data', async (data) => {
|
|
76
100
|
const output = data.toString();
|
|
101
|
+
|
|
77
102
|
if (!tunnelStarted && (output.includes('Local:') || output.includes('Compiled successfully'))) {
|
|
78
103
|
tunnelStarted = true;
|
|
79
|
-
console.log(\`\\n[Fleetbo] 🔗 React is ready.
|
|
104
|
+
console.log(\`\\n[Fleetbo] 🔗 React is ready. Initiating Tunnel...\`);
|
|
80
105
|
|
|
81
106
|
try {
|
|
82
|
-
|
|
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
|
+
});
|
|
83
112
|
await syncFirebase(keyApp, url);
|
|
84
|
-
} catch (
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
+
}
|
|
92
128
|
}
|
|
93
|
-
cleanupAndExit(1);
|
|
94
129
|
}
|
|
95
130
|
}
|
|
96
131
|
});
|
|
@@ -102,11 +137,17 @@ runGuardian();
|
|
|
102
137
|
// --- Analyse des Arguments ---
|
|
103
138
|
const args = process.argv.slice(2);
|
|
104
139
|
const projectNameArg = args.find(arg => !arg.startsWith('--'));
|
|
140
|
+
|
|
141
|
+
// Argument Token Fleetbo
|
|
105
142
|
const tokenArg = args.find(arg => arg.startsWith('--token='));
|
|
106
143
|
const bootstrapTokenArg = tokenArg ? tokenArg.split('=')[1] : null;
|
|
107
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
|
+
|
|
108
149
|
if (!projectNameArg || !bootstrapTokenArg) {
|
|
109
|
-
console.error('\n ❌ Usage: npx create-fleetbo-project <
|
|
150
|
+
console.error('\n ❌ Usage: npx create-fleetbo-project <name> --token=<fleetbo-token> [--ngrok=<ngrok-token>]');
|
|
110
151
|
process.exit(1);
|
|
111
152
|
}
|
|
112
153
|
|
|
@@ -118,8 +159,17 @@ const projectDir = path.join(process.cwd(), projectName);
|
|
|
118
159
|
function fetchProjectKeys(token) {
|
|
119
160
|
return new Promise((resolve, reject) => {
|
|
120
161
|
const postData = JSON.stringify({ token });
|
|
121
|
-
const
|
|
122
|
-
const
|
|
162
|
+
const uri = new URL(bootstrapUrl);
|
|
163
|
+
const options = {
|
|
164
|
+
hostname: uri.hostname,
|
|
165
|
+
path: uri.pathname,
|
|
166
|
+
method: 'POST',
|
|
167
|
+
headers: {
|
|
168
|
+
'Content-Type': 'application/json',
|
|
169
|
+
'Content-Length': Buffer.byteLength(postData)
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
const req = https.request(options, (res) => {
|
|
123
173
|
let data = '';
|
|
124
174
|
res.on('data', (chunk) => { data += chunk; });
|
|
125
175
|
res.on('end', () => {
|
|
@@ -136,18 +186,49 @@ function fetchProjectKeys(token) {
|
|
|
136
186
|
|
|
137
187
|
function downloadEngine(url, dest) {
|
|
138
188
|
return new Promise((resolve, reject) => {
|
|
139
|
-
const
|
|
189
|
+
const uri = new URL(url);
|
|
190
|
+
const options = {
|
|
191
|
+
hostname: uri.hostname,
|
|
192
|
+
path: uri.pathname + uri.search,
|
|
193
|
+
method: 'GET',
|
|
194
|
+
headers: {
|
|
195
|
+
'User-Agent': 'Fleetbo-CLI-Installer',
|
|
196
|
+
'Accept': '*/*'
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const request = https.get(options, (response) => {
|
|
140
201
|
if (response.statusCode === 301 || response.statusCode === 302) {
|
|
202
|
+
if (!response.headers.location) {
|
|
203
|
+
reject(new Error("Redirect found but no location header"));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
141
206
|
downloadEngine(response.headers.location, dest).then(resolve).catch(reject);
|
|
142
207
|
return;
|
|
143
208
|
}
|
|
144
|
-
|
|
209
|
+
|
|
210
|
+
if (response.statusCode !== 200) {
|
|
211
|
+
reject(new Error(`Failed to download (Status: ${response.statusCode})`));
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
145
215
|
const file = fs.createWriteStream(dest);
|
|
146
216
|
response.pipe(file);
|
|
147
|
-
|
|
148
|
-
file.on('
|
|
217
|
+
|
|
218
|
+
file.on('finish', () => {
|
|
219
|
+
file.close(resolve);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
file.on('error', (err) => {
|
|
223
|
+
fs.unlink(dest, () => {});
|
|
224
|
+
reject(err);
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
request.on('error', (err) => {
|
|
229
|
+
fs.unlink(dest, () => {});
|
|
230
|
+
reject(err);
|
|
149
231
|
});
|
|
150
|
-
request.on('error', (err) => reject(err));
|
|
151
232
|
});
|
|
152
233
|
}
|
|
153
234
|
|
|
@@ -180,14 +261,27 @@ async function setupProject() {
|
|
|
180
261
|
|
|
181
262
|
// 4. Environment & CLI Generation
|
|
182
263
|
console.log(' [4/6] ⚙️ Configuring environment & CLI...');
|
|
183
|
-
|
|
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
|
+
|
|
184
279
|
fs.writeFileSync(path.join(projectDir, '.env'), envContent, 'utf8');
|
|
185
280
|
fs.writeFileSync(path.join(projectDir, 'cli.js'), CLI_SCRIPT_CONTENT, 'utf8');
|
|
186
281
|
|
|
187
282
|
// 5. Deps
|
|
188
283
|
console.log(' [5/6] 📚 Installing dependencies...');
|
|
189
284
|
execSync('npm install', { stdio: 'inherit' });
|
|
190
|
-
// AJOUT DE AXIOS ICI
|
|
191
285
|
execSync('npm install ngrok dotenv axios --save-dev', { stdio: 'ignore' });
|
|
192
286
|
|
|
193
287
|
// 6. Finalize
|
|
@@ -198,7 +292,7 @@ async function setupProject() {
|
|
|
198
292
|
packageJson.scripts = { ...packageJson.scripts, "fleetbo": "node cli.js", "dev": "node cli.js" };
|
|
199
293
|
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8');
|
|
200
294
|
|
|
201
|
-
console.log('\n✅ Project successfully created!');
|
|
295
|
+
console.log('\n [Fleetbo] ✅ Project successfully created!');
|
|
202
296
|
console.log(`\n👉 Run: cd ${projectName} && npm run fleetbo`);
|
|
203
297
|
|
|
204
298
|
} catch (error) {
|