create-fleetbo-project 1.2.30 → 1.2.32

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');
@@ -24,7 +22,10 @@ const os = require('os');
24
22
 
25
23
  const args = process.argv.slice(2);
26
24
  const command = args[0];
27
- const GENERATOR_COMMANDS = ['page', 'g', 'generate'];
25
+
26
+
27
+ const GENERATOR_COMMANDS = ['page', 'g', 'generate', 'android', 'ios'];
28
+
28
29
  if (GENERATOR_COMMANDS.includes(command)) {
29
30
  try {
30
31
  require('./page.js');
@@ -44,8 +45,8 @@ if (GENERATOR_COMMANDS.includes(command)) {
44
45
  const UPDATE_NETWORK_URL = 'https://us-central1-myapp-259bf.cloudfunctions.net/updateDeveloperNetwork';
45
46
  const PORT = 3000;
46
47
 
47
-
48
48
  const NULL_DEV = process.platform === 'win32' ? '>nul 2>&1' : '2>/dev/null';
49
+
49
50
  function killProcessOnPort(port) {
50
51
  try {
51
52
  if (process.platform !== 'win32') {
@@ -60,7 +61,7 @@ function killProcessOnPort(port) {
60
61
  function killNetworkService() {
61
62
  try {
62
63
  const cmd = process.platform === 'win32' ? 'taskkill /IM cloudflared.exe /F' : 'pkill cloudflared';
63
- execSync(cmd + ' ' + NULL_DEV); // Utilisation de la variable adaptée
64
+ execSync(cmd + ' ' + NULL_DEV);
64
65
  } catch (e) {}
65
66
  }
66
67
 
@@ -93,7 +94,6 @@ async function syncFirebase(keyApp, networkUrl, testerEmail) {
93
94
  async function runDevEnvironment() {
94
95
  console.log(\`[Fleetbo] 🛡️ Initializing Developer Environment on \${os.platform()}...\`);
95
96
 
96
- // 1. NETTOYAGE PRÉVENTIF
97
97
  killNetworkService();
98
98
  killProcessOnPort(PORT);
99
99
 
@@ -111,7 +111,6 @@ async function runDevEnvironment() {
111
111
  process.exit(1);
112
112
  }
113
113
 
114
- // 2. DÉMARRAGE DU SERVEUR LOCAL
115
114
  console.log(\`[Fleetbo] 📦 Starting Local Server...\`);
116
115
  const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
117
116
 
@@ -133,11 +132,10 @@ async function runDevEnvironment() {
133
132
  connectionStarted = true;
134
133
  console.log(\`\\n[Fleetbo] 🔗 Local Server Ready. Establishing Secure Uplink...\`);
135
134
 
136
- // 3. DÉMARRAGE DE LA LIAISON (UPLINK)
137
135
  const npxCmd = process.platform === 'win32' ? 'npx.cmd' : 'npx';
136
+
138
137
  const uplink = spawn(npxCmd, ['cloudflared', 'tunnel', '--url', \`http://localhost:\${PORT}\`], { shell: true });
139
138
 
140
- // Capture de l'URL (Silencieux)
141
139
  uplink.stderr.on('data', (chunk) => {
142
140
  const log = chunk.toString();
143
141
 
@@ -162,7 +160,7 @@ async function runDevEnvironment() {
162
160
  runDevEnvironment();
163
161
  `;
164
162
 
165
- // --- Analyse des Arguments ---
163
+ // --- LOGIQUE D'INSTALLATION (INCHANGÉE) ---
166
164
  const args = process.argv.slice(2);
167
165
  const projectNameArg = args.find(arg => !arg.startsWith('--'));
168
166
  const tokenArg = args.find(arg => arg.startsWith('--token='));
@@ -179,7 +177,6 @@ if (!projectNameArg || !bootstrapTokenArg || !userEmailArg) {
179
177
  const projectName = projectNameArg;
180
178
  const projectDir = path.join(process.cwd(), projectName);
181
179
 
182
- // --- Fonctions Utilitaires ---
183
180
  function fetchProjectKeys(token) {
184
181
  return new Promise((resolve, reject) => {
185
182
  const postData = JSON.stringify({ token });
@@ -226,7 +223,6 @@ function downloadEngine(url, dest) {
226
223
  });
227
224
  }
228
225
 
229
- // --- Fonction Principale ---
230
226
  async function setupProject() {
231
227
  console.log(`\n⚡ Initializing Fleetbo Framework for "${projectName}"...`);
232
228
 
@@ -261,19 +257,16 @@ async function setupProject() {
261
257
  `;
262
258
 
263
259
  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
260
  const scriptsDir = path.join(projectDir, 'scripts');
266
261
  if (!fs.existsSync(scriptsDir)) {
267
262
  fs.mkdirSync(scriptsDir, { recursive: true });
268
263
  }
269
264
  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
265
  try { fs.chmodSync(path.join(scriptsDir, 'cli.js'), '755'); } catch (e) {}
272
266
 
273
267
  console.log(' [5/6] 📚 Installing dependencies...');
274
268
  execSync('npm install', { stdio: 'inherit' });
275
269
 
276
- // Installation silencieuse
277
270
  execSync('npm install cloudflared dotenv axios --save-dev', { stdio: 'ignore' });
278
271
 
279
272
  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.30",
3
+ "version": "1.2.32",
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();