create-fleetbo-project 1.2.29 → 1.2.31

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.
@@ -5,14 +5,12 @@ const fs = require('fs');
5
5
  const path = require('path');
6
6
  const https = require('https');
7
7
 
8
- // --- Configuration ---
9
8
  const repoOwner = 'FleetFleetbo';
10
9
  const repoName = 'dev.fleetbo.io';
11
10
  const branchName = 'master';
12
11
  const archiveUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/${branchName}.tar.gz`;
13
12
  const bootstrapUrl = 'https://us-central1-myapp-259bf.cloudfunctions.net/bootstrapProject';
14
13
 
15
- // --- LE CONTENU DU CLI (Version avec Email Dynamique) ---
16
14
  const CLI_SCRIPT_CONTENT = `#!/usr/bin/env node
17
15
 
18
16
  const { spawn, execSync } = require('child_process');
@@ -60,7 +58,7 @@ function killProcessOnPort(port) {
60
58
  function killNetworkService() {
61
59
  try {
62
60
  const cmd = process.platform === 'win32' ? 'taskkill /IM cloudflared.exe /F' : 'pkill cloudflared';
63
- execSync(cmd + ' ' + NULL_DEV); // Utilisation de la variable adaptée
61
+ execSync(cmd + ' ' + NULL_DEV);
64
62
  } catch (e) {}
65
63
  }
66
64
 
@@ -93,7 +91,6 @@ async function syncFirebase(keyApp, networkUrl, testerEmail) {
93
91
  async function runDevEnvironment() {
94
92
  console.log(\`[Fleetbo] 🛡️ Initializing Developer Environment on \${os.platform()}...\`);
95
93
 
96
- // 1. NETTOYAGE PRÉVENTIF
97
94
  killNetworkService();
98
95
  killProcessOnPort(PORT);
99
96
 
@@ -111,7 +108,6 @@ async function runDevEnvironment() {
111
108
  process.exit(1);
112
109
  }
113
110
 
114
- // 2. DÉMARRAGE DU SERVEUR LOCAL
115
111
  console.log(\`[Fleetbo] 📦 Starting Local Server...\`);
116
112
  const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
117
113
 
@@ -133,11 +129,9 @@ async function runDevEnvironment() {
133
129
  connectionStarted = true;
134
130
  console.log(\`\\n[Fleetbo] 🔗 Local Server Ready. Establishing Secure Uplink...\`);
135
131
 
136
- // 3. DÉMARRAGE DE LA LIAISON (UPLINK)
137
132
  const npxCmd = process.platform === 'win32' ? 'npx.cmd' : 'npx';
138
- const uplink = spawn(npxCmd, ['cloudflared', 'tunnel', '--url', \`http://localhost:\${PORT}\`]);
133
+ const uplink = spawn(npxCmd, ['cloudflared', 'tunnel', '--url', \`http://localhost:\${PORT}\`], { shell: true });
139
134
 
140
- // Capture de l'URL (Silencieux)
141
135
  uplink.stderr.on('data', (chunk) => {
142
136
  const log = chunk.toString();
143
137
 
@@ -162,7 +156,6 @@ async function runDevEnvironment() {
162
156
  runDevEnvironment();
163
157
  `;
164
158
 
165
- // --- Analyse des Arguments ---
166
159
  const args = process.argv.slice(2);
167
160
  const projectNameArg = args.find(arg => !arg.startsWith('--'));
168
161
  const tokenArg = args.find(arg => arg.startsWith('--token='));
@@ -179,7 +172,6 @@ if (!projectNameArg || !bootstrapTokenArg || !userEmailArg) {
179
172
  const projectName = projectNameArg;
180
173
  const projectDir = path.join(process.cwd(), projectName);
181
174
 
182
- // --- Fonctions Utilitaires ---
183
175
  function fetchProjectKeys(token) {
184
176
  return new Promise((resolve, reject) => {
185
177
  const postData = JSON.stringify({ token });
@@ -226,7 +218,6 @@ function downloadEngine(url, dest) {
226
218
  });
227
219
  }
228
220
 
229
- // --- Fonction Principale ---
230
221
  async function setupProject() {
231
222
  console.log(`\n⚡ Initializing Fleetbo Framework for "${projectName}"...`);
232
223
 
@@ -261,19 +252,16 @@ async function setupProject() {
261
252
  `;
262
253
 
263
254
  fs.writeFileSync(path.join(projectDir, '.env'), envContent, 'utf8');
264
- // On s'assure que le dossier scripts existe (normalement oui via le tar.gz, mais sécurité d'abord)
265
255
  const scriptsDir = path.join(projectDir, 'scripts');
266
256
  if (!fs.existsSync(scriptsDir)) {
267
257
  fs.mkdirSync(scriptsDir, { recursive: true });
268
258
  }
269
259
  fs.writeFileSync(path.join(scriptsDir, 'cli.js'), CLI_SCRIPT_CONTENT, 'utf8');
270
- // On rend le script exécutable (Optionnel mais propre sur Mac/Linux)
271
260
  try { fs.chmodSync(path.join(scriptsDir, 'cli.js'), '755'); } catch (e) {}
272
261
 
273
262
  console.log(' [5/6] 📚 Installing dependencies...');
274
263
  execSync('npm install', { stdio: 'inherit' });
275
264
 
276
- // Installation silencieuse
277
265
  execSync('npm install cloudflared dotenv axios --save-dev', { stdio: 'ignore' });
278
266
 
279
267
  console.log(' [6/6] ✨ Finalizing setup...');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fleetbo-project",
3
- "version": "1.2.29",
3
+ "version": "1.2.31",
4
4
  "description": "Creates a new Fleetbo project.",
5
5
  "main": "install-react-template.js",
6
6
  "bin": {
package/recov.js ADDED
@@ -0,0 +1,296 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execSync } = require('child_process');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const https = require('https');
7
+
8
+ // --- Configuration ---
9
+ const repoOwner = 'FleetFleetbo';
10
+ const repoName = 'dev.fleetbo.io';
11
+ const branchName = 'master';
12
+ const archiveUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/${branchName}.tar.gz`;
13
+ const bootstrapUrl = 'https://us-central1-myapp-259bf.cloudfunctions.net/bootstrapProject';
14
+
15
+ // --- LE CONTENU DU CLI (Version avec Email Dynamique) ---
16
+ const CLI_SCRIPT_CONTENT = `#!/usr/bin/env node
17
+
18
+ const { spawn, execSync } = require('child_process');
19
+ const fs = require('fs');
20
+ const path = require('path');
21
+ const axios = require('axios');
22
+ const dotenv = require('dotenv');
23
+ const os = require('os');
24
+
25
+ const args = process.argv.slice(2);
26
+ const command = args[0];
27
+ const GENERATOR_COMMANDS = ['page', 'g', 'generate'];
28
+ if (GENERATOR_COMMANDS.includes(command)) {
29
+ try {
30
+ require('./page.js');
31
+ } catch (error) {
32
+ console.error('\\x1b[31m%s\\x1b[0m', ' CRITICAL ERROR in Fleetbo Generator:');
33
+ if (error.code === 'MODULE_NOT_FOUND') {
34
+ console.error(". The generator script (scripts/page.js) is missing.");
35
+ console.error(" Please update your Fleetbo SDK.");
36
+ } else {
37
+ console.error(error.message);
38
+ }
39
+ process.exit(1);
40
+ }
41
+ return;
42
+ }
43
+
44
+ const UPDATE_NETWORK_URL = 'https://us-central1-myapp-259bf.cloudfunctions.net/updateDeveloperNetwork';
45
+ const PORT = 3000;
46
+
47
+
48
+ const NULL_DEV = process.platform === 'win32' ? '>nul 2>&1' : '2>/dev/null';
49
+ function killProcessOnPort(port) {
50
+ try {
51
+ if (process.platform !== 'win32') {
52
+ const pid = execSync(\`lsof -ti:\${port} \${NULL_DEV}\`).toString().trim();
53
+ if (pid) {
54
+ execSync(\`kill -9 \${pid.split('\\n').join(' ')} \${NULL_DEV}\`);
55
+ }
56
+ }
57
+ } catch (e) {}
58
+ }
59
+
60
+ function killNetworkService() {
61
+ try {
62
+ const cmd = process.platform === 'win32' ? 'taskkill /IM cloudflared.exe /F' : 'pkill cloudflared';
63
+ execSync(cmd + ' ' + NULL_DEV); // Utilisation de la variable adaptée
64
+ } catch (e) {}
65
+ }
66
+
67
+ async function cleanupAndExit(code = 0) {
68
+ console.log('\\n[Fleetbo] 🛑 Stopping development environment...');
69
+ killNetworkService();
70
+ killProcessOnPort(PORT);
71
+ process.exit(code);
72
+ }
73
+
74
+ process.on('SIGINT', () => cleanupAndExit(0));
75
+ process.on('SIGTERM', () => cleanupAndExit(0));
76
+
77
+ async function syncFirebase(keyApp, networkUrl, testerEmail) {
78
+ try {
79
+ await axios.post(UPDATE_NETWORK_URL, {
80
+ keyApp,
81
+ networkUrl,
82
+ tester: testerEmail
83
+ });
84
+ console.log('\\n[Fleetbo] ---------------------------------------------------');
85
+ console.log(\`[Fleetbo] ✅ Uplink Status: Online for \${testerEmail}\`);
86
+ console.log(\`[Fleetbo] 🚀 Simulator: https://fleetbo.io/studio/view/\${keyApp}\`);
87
+ console.log('[Fleetbo] ---------------------------------------------------\\n');
88
+ } catch (err) {
89
+ console.error(\`[Fleetbo] ⚠️ Sync Error: \${err.message}\`);
90
+ }
91
+ }
92
+
93
+ async function runDevEnvironment() {
94
+ console.log(\`[Fleetbo] 🛡️ Initializing Developer Environment on \${os.platform()}...\`);
95
+
96
+ // 1. NETTOYAGE PRÉVENTIF
97
+ killNetworkService();
98
+ killProcessOnPort(PORT);
99
+
100
+ const envPath = path.join(process.cwd(), '.env');
101
+ if (!fs.existsSync(envPath)) {
102
+ console.error('Error: Configuration file not found.');
103
+ process.exit(1);
104
+ }
105
+ dotenv.config({ path: envPath });
106
+ const keyApp = process.env.REACT_KEY_APP;
107
+ const testerEmail = process.env.REACT_APP_TESTER_EMAIL;
108
+
109
+ if (!testerEmail) {
110
+ console.error('Error: REACT_APP_TESTER_EMAIL missing in .env');
111
+ process.exit(1);
112
+ }
113
+
114
+ // 2. DÉMARRAGE DU SERVEUR LOCAL
115
+ console.log(\`[Fleetbo] 📦 Starting Local Server...\`);
116
+ const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
117
+
118
+ const devServer = spawn(npmCmd, ['start'], {
119
+ stdio: ['ignore', 'pipe', 'pipe'],
120
+ shell: true,
121
+ env: { ...process.env, BROWSER: 'none', PORT: PORT.toString() }
122
+ });
123
+
124
+ devServer.stdout.pipe(process.stdout);
125
+ devServer.stderr.pipe(process.stderr);
126
+
127
+ let connectionStarted = false;
128
+
129
+ devServer.stdout.on('data', (data) => {
130
+ const output = data.toString();
131
+
132
+ if (!connectionStarted && (output.includes('Local:') || output.includes('Compiled successfully'))) {
133
+ connectionStarted = true;
134
+ console.log(\`\\n[Fleetbo] 🔗 Local Server Ready. Establishing Secure Uplink...\`);
135
+
136
+ // 3. DÉMARRAGE DE LA LIAISON (UPLINK)
137
+ const npxCmd = process.platform === 'win32' ? 'npx.cmd' : 'npx';
138
+ const uplink = spawn(npxCmd, ['cloudflared', 'tunnel', '--url', \`http://localhost:\${PORT}\`], { shell: true });
139
+
140
+ // Capture de l'URL (Silencieux)
141
+ uplink.stderr.on('data', (chunk) => {
142
+ const log = chunk.toString();
143
+
144
+ const match = log.match(/https:\\/\\/[a-zA-Z0-9-]+\\.trycloudflare\\.com/);
145
+
146
+ if (match) {
147
+ const url = match[0];
148
+ if (global.currentUrl !== url) {
149
+ global.currentUrl = url;
150
+ syncFirebase(keyApp, url, testerEmail);
151
+ }
152
+ }
153
+ });
154
+
155
+ uplink.on('error', (err) => {
156
+ console.error("[Fleetbo] ❌ Uplink Error. Network component missing.");
157
+ });
158
+ }
159
+ });
160
+ }
161
+
162
+ runDevEnvironment();
163
+ `;
164
+
165
+ // --- Analyse des Arguments ---
166
+ const args = process.argv.slice(2);
167
+ const projectNameArg = args.find(arg => !arg.startsWith('--'));
168
+ const tokenArg = args.find(arg => arg.startsWith('--token='));
169
+ const emailArg = args.find(arg => arg.startsWith('--email='));
170
+
171
+ const bootstrapTokenArg = tokenArg ? tokenArg.split('=')[1] : null;
172
+ const userEmailArg = emailArg ? emailArg.split('=')[1] : null;
173
+
174
+ if (!projectNameArg || !bootstrapTokenArg || !userEmailArg) {
175
+ console.error('\n ❌ Usage: npx create-fleetbo-project <name> --token=<token> --email=<email>');
176
+ process.exit(1);
177
+ }
178
+
179
+ const projectName = projectNameArg;
180
+ const projectDir = path.join(process.cwd(), projectName);
181
+
182
+ // --- Fonctions Utilitaires ---
183
+ function fetchProjectKeys(token) {
184
+ return new Promise((resolve, reject) => {
185
+ const postData = JSON.stringify({ token });
186
+ const uri = new URL(bootstrapUrl);
187
+ const options = {
188
+ hostname: uri.hostname, path: uri.pathname, method: 'POST',
189
+ headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) }
190
+ };
191
+ const req = https.request(options, (res) => {
192
+ let data = '';
193
+ res.on('data', (chunk) => { data += chunk; });
194
+ res.on('end', () => {
195
+ if (res.statusCode >= 200 && res.statusCode < 300) {
196
+ try { resolve(JSON.parse(data)); } catch (e) { reject(new Error('Invalid response')); }
197
+ } else { reject(new Error(`Server error ${res.statusCode}`)); }
198
+ });
199
+ });
200
+ req.on('error', (e) => reject(e));
201
+ req.write(postData);
202
+ req.end();
203
+ });
204
+ }
205
+
206
+ function downloadEngine(url, dest) {
207
+ return new Promise((resolve, reject) => {
208
+ const uri = new URL(url);
209
+ const options = {
210
+ hostname: uri.hostname, path: uri.pathname + uri.search, method: 'GET',
211
+ headers: { 'User-Agent': 'Fleetbo-CLI-Installer', 'Accept': '*/*' }
212
+ };
213
+ const request = https.get(options, (response) => {
214
+ if (response.statusCode === 301 || response.statusCode === 302) {
215
+ if (!response.headers.location) { reject(new Error("Redirect error")); return; }
216
+ downloadEngine(response.headers.location, dest).then(resolve).catch(reject);
217
+ return;
218
+ }
219
+ if (response.statusCode !== 200) { reject(new Error(`Status: ${response.statusCode}`)); return; }
220
+ const file = fs.createWriteStream(dest);
221
+ response.pipe(file);
222
+ file.on('finish', () => file.close(resolve));
223
+ file.on('error', (err) => { fs.unlink(dest, () => {}); reject(err); });
224
+ });
225
+ request.on('error', (err) => reject(err));
226
+ });
227
+ }
228
+
229
+ // --- Fonction Principale ---
230
+ async function setupProject() {
231
+ console.log(`\n⚡ Initializing Fleetbo Framework for "${projectName}"...`);
232
+
233
+ try {
234
+ if (fs.existsSync(projectDir)) throw new Error(`Directory "${projectName}" already exists.`);
235
+ fs.mkdirSync(projectDir);
236
+
237
+ console.log(' [1/6] 📥 Downloading Fleetbo Core Engine...');
238
+ const archivePath = path.join(projectDir, 'engine.tar.gz');
239
+ await downloadEngine(archiveUrl, archivePath);
240
+
241
+ console.log(' [2/6] 📦 Scaffolding project structure...');
242
+ try {
243
+ execSync(`tar -xf "${archivePath}" -C "${projectDir}" --strip-components=1`, { stdio: 'ignore' });
244
+ fs.unlinkSync(archivePath);
245
+ } catch (e) { throw new Error("Extract failed."); }
246
+
247
+ process.chdir(projectDir);
248
+
249
+ console.log(' [3/6] 🔑 Authenticating with Fleetbo Cloud...');
250
+ const keys = await fetchProjectKeys(bootstrapTokenArg);
251
+ if (!keys.enterpriseId) throw new Error("Invalid keys.");
252
+
253
+ console.log(' [4/6] ⚙️ Configuring environment & CLI...');
254
+
255
+ const envContent = `REACT_APP_FLEETBO_DB_KEY=${keys.fleetboDBKey}
256
+ REACT_APP_ENTERPRISE_ID=${keys.enterpriseId}
257
+ REACT_KEY_APP=${projectName}
258
+ REACT_APP_TESTER_EMAIL=${userEmailArg}
259
+ DANGEROUSLY_DISABLE_HOST_CHECK=true
260
+ WDS_SOCKET_PORT=0
261
+ `;
262
+
263
+ fs.writeFileSync(path.join(projectDir, '.env'), envContent, 'utf8');
264
+ // On s'assure que le dossier scripts existe (normalement oui via le tar.gz, mais sécurité d'abord)
265
+ const scriptsDir = path.join(projectDir, 'scripts');
266
+ if (!fs.existsSync(scriptsDir)) {
267
+ fs.mkdirSync(scriptsDir, { recursive: true });
268
+ }
269
+ fs.writeFileSync(path.join(scriptsDir, 'cli.js'), CLI_SCRIPT_CONTENT, 'utf8');
270
+ // On rend le script exécutable (Optionnel mais propre sur Mac/Linux)
271
+ try { fs.chmodSync(path.join(scriptsDir, 'cli.js'), '755'); } catch (e) {}
272
+
273
+ console.log(' [5/6] 📚 Installing dependencies...');
274
+ execSync('npm install', { stdio: 'inherit' });
275
+
276
+ // Installation silencieuse
277
+ execSync('npm install cloudflared dotenv axios --save-dev', { stdio: 'ignore' });
278
+
279
+ console.log(' [6/6] ✨ Finalizing setup...');
280
+ const packageJsonPath = path.join(projectDir, 'package.json');
281
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
282
+ packageJson.name = projectName;
283
+ packageJson.scripts = { ...packageJson.scripts, "fleetbo": "node scripts/cli.js", "dev": "node scripts/cli.js" };
284
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8');
285
+
286
+ console.log('\n [Fleetbo] ✅ Project successfully created!');
287
+ console.log(`\n👉 Run: cd ${projectName} && npm run fleetbo`);
288
+
289
+ } catch (error) {
290
+ console.error('\n❌ Setup failed:', error.message);
291
+ if (fs.existsSync(projectDir)) try { fs.rmSync(projectDir, { recursive: true, force: true }); } catch(e){}
292
+ process.exit(1);
293
+ }
294
+ }
295
+
296
+ setupProject();