create-fleetbo-project 1.2.97 → 1.2.98

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.
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // 🥷 SILENCIEUX ABSOLU : S'exécute instantanément pour tuer la plomberie de NPX
3
4
  process.stdout.write("\x1b[1A\x1b[2K".repeat(4));
4
5
  console.clear();
5
6
 
@@ -15,54 +16,61 @@ const projectNameArg = args.find(arg => !arg.startsWith('--'));
15
16
  const tokenArg = args.find(arg => arg.startsWith('--token='));
16
17
  const emailArg = args.find(arg => arg.startsWith('--email='));
17
18
  const frameworkArg = args.find(arg => arg.startsWith('--framework='));
18
-
19
19
  const bootstrapTokenArg = tokenArg ? tokenArg.split('=')[1] : null;
20
20
  const userEmailArg = emailArg ? emailArg.split('=')[1] : null;
21
- const framework = frameworkArg ? frameworkArg.split('=')[1].toLowerCase() : 'react';
21
+ const jsFramework = frameworkArg ? frameworkArg.split('=')[1] : 'react';
22
22
 
23
23
  if (!projectNameArg || !bootstrapTokenArg || !userEmailArg) {
24
- console.error('\n Usage: npx create-fleetbo-project <name> --token=<token> --email=<email> [--framework=react|vue]');
24
+ console.error('\n Usage: npx create-fleetbo-project <n> --token=<token> --email=<email> [--framework=vue]');
25
25
  process.exit(1);
26
26
  }
27
27
 
28
- const projectName = projectNameArg;
29
- const projectDir = path.join(process.cwd(), projectName);
30
-
31
- // 🌐 SÉLECTION DYNAMIQUE DE LA SOURCE
32
- let archiveUrl;
33
- if (framework === 'vue') {
34
- console.log(`\n 🔍 Resolving latest Vue template from npm registry...`);
28
+ // 🌐 RÉSOLUTION UNIFIÉE DEPUIS NPM
29
+ // React : my-fleetbo-react | Vue : my-fleetbo-vue
30
+ // NPM = CDN industriel, SemVer, zéro rate limit GitHub
31
+ const getArchiveUrl = () => {
32
+ const templatePackage = jsFramework === 'vue' ? 'my-fleetbo-vue' : 'my-fleetbo-react';
33
+ console.log(` 🔍 Resolving latest ${jsFramework.toUpperCase()} template from npm registry...`);
35
34
  try {
36
- archiveUrl = execSync('npm view my-fleetbo-vue dist.tarball', { stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim();
35
+ const tarball = execSync(`npm view ${templatePackage} dist.tarball`, { stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim();
36
+ if (!tarball) throw new Error('Empty response');
37
+ return Promise.resolve(tarball);
37
38
  } catch (e) {
38
- console.error('\n Error: Could not locate "my-fleetbo-vue" on npm.');
39
- process.exit(1);
39
+ return Promise.reject(new Error(`Could not locate "${templatePackage}" on npm. Is it published?`));
40
40
  }
41
- } else {
42
- const repoOwner = 'FleetFleetbo';
43
- const repoName = 'dev.fleetbo.io';
44
- const branchName = 'master';
45
- archiveUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/${branchName}.tar.gz`;
46
- }
41
+ };
42
+
43
+ const projectName = projectNameArg;
44
+ const projectDir = path.join(process.cwd(), projectName);
47
45
 
48
46
  function fetchProjectKeys(token) {
49
47
  return new Promise((resolve, reject) => {
50
48
  const postData = JSON.stringify({ token });
51
49
  const uri = new URL(bootstrapUrl);
52
50
  const options = {
53
- hostname: uri.hostname, path: uri.pathname, method: 'POST',
54
- headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) }
51
+ hostname: uri.hostname,
52
+ path: uri.pathname,
53
+ method: 'POST',
54
+ headers: {
55
+ 'Content-Type': 'application/json',
56
+ 'Content-Length': Buffer.byteLength(postData)
57
+ }
55
58
  };
56
59
  const req = https.request(options, (res) => {
57
60
  let data = '';
58
61
  res.on('data', (chunk) => { data += chunk; });
59
62
  res.on('end', () => {
60
63
  if (res.statusCode >= 200 && res.statusCode < 300) {
61
- try { resolve(JSON.parse(data)); } catch (e) { reject(new Error('Invalid response')); }
62
- } else { reject(new Error(`Server error ${res.statusCode}`)); }
64
+ try { resolve(JSON.parse(data)); }
65
+ catch (e) { reject(new Error('Invalid response')); }
66
+ } else {
67
+ reject(new Error(`Server error ${res.statusCode}`));
68
+ }
63
69
  });
64
70
  });
65
- req.on('error', (e) => reject(e)); req.write(postData); req.end();
71
+ req.on('error', (e) => reject(e));
72
+ req.write(postData);
73
+ req.end();
66
74
  });
67
75
  }
68
76
 
@@ -70,33 +78,51 @@ function downloadEngine(url, dest) {
70
78
  return new Promise((resolve, reject) => {
71
79
  const uri = new URL(url);
72
80
  const options = {
73
- hostname: uri.hostname, path: uri.pathname + uri.search, method: 'GET',
74
- headers: { 'User-Agent': 'Fleetbo-CLI-Installer', 'Accept': '*/*' }
81
+ hostname: uri.hostname,
82
+ path: uri.pathname + uri.search,
83
+ method: 'GET',
84
+ headers: {
85
+ 'User-Agent': 'Fleetbo-CLI-Installer',
86
+ 'Accept': '*/*'
87
+ }
75
88
  };
76
89
  const request = https.get(options, (response) => {
77
90
  if (response.statusCode === 301 || response.statusCode === 302) {
78
- if (!response.headers.location) { reject(new Error("Redirect error")); return; }
91
+ if (!response.headers.location) {
92
+ reject(new Error("Redirect error"));
93
+ return;
94
+ }
79
95
  downloadEngine(response.headers.location, dest).then(resolve).catch(reject);
80
96
  return;
81
97
  }
82
- if (response.statusCode !== 200) { reject(new Error(`Status: ${response.statusCode}`)); return; }
98
+ if (response.statusCode !== 200) {
99
+ reject(new Error(`Status: ${response.statusCode}`));
100
+ return;
101
+ }
83
102
  const file = fs.createWriteStream(dest);
84
103
  response.pipe(file);
85
104
  file.on('finish', () => file.close(resolve));
86
- file.on('error', (err) => { fs.unlink(dest, () => {}); reject(err); });
105
+ file.on('error', (err) => {
106
+ fs.unlink(dest, () => {});
107
+ reject(err);
108
+ });
87
109
  });
88
110
  request.on('error', (err) => reject(err));
89
111
  });
90
112
  }
91
113
 
92
114
  async function setupProject() {
93
- console.log(`\n ⚡ Initializing Fleetbo Framework (\x1b[36m${framework.toUpperCase()}\x1b[0m) for "${projectName}"...`);
115
+ console.log(`\n ⚡ Initializing Fleetbo Framework for "${projectName}"...`);
94
116
 
95
117
  try {
96
- if (fs.existsSync(projectDir)) { throw new Error(`Directory "${projectName}" already exists.`); }
118
+ if (fs.existsSync(projectDir)) {
119
+ throw new Error(`Directory "${projectName}" already exists.`);
120
+ }
97
121
  fs.mkdirSync(projectDir);
98
122
 
99
- console.log(' [1/8] Downloading Fleetbo Core Engine...');
123
+ const frameworkLabel = jsFramework === 'vue' ? 'Vue' : 'React';
124
+ console.log(` [1/8] Downloading Fleetbo ${frameworkLabel} Engine...`);
125
+ const archiveUrl = await getArchiveUrl();
100
126
  const archivePath = path.join(projectDir, 'engine.tar.gz');
101
127
  await downloadEngine(archiveUrl, archivePath);
102
128
 
@@ -104,17 +130,19 @@ async function setupProject() {
104
130
  try {
105
131
  execSync(`tar -xf "${archivePath}" -C "${projectDir}" --strip-components=1`, { stdio: 'ignore' });
106
132
  fs.unlinkSync(archivePath);
107
- } catch (e) { throw new Error("Extract failed."); }
133
+ } catch (e) {
134
+ throw new Error("Extract failed.");
135
+ }
108
136
 
109
137
  process.chdir(projectDir);
110
138
 
111
- console.log(' [3/8] Standardizing Architecture...');
112
- if (framework === 'react') {
113
- const oldPath = path.join(projectDir, 'src/pages');
114
- const newPath = path.join(projectDir, 'src/app');
115
- if (fs.existsSync(oldPath) && !fs.existsSync(newPath)) {
116
- try { fs.renameSync(oldPath, newPath); } catch (err) {}
117
- }
139
+ console.log(' [3/8] Standardizing Architecture (Vite)...');
140
+ // Pour Vite, on s'assure juste que l'arborescence de base est correcte.
141
+ // On retire les vieux renommages CRA (App.js) pour éviter de casser App.jsx
142
+ const oldPath = path.join(projectDir, 'src/pages');
143
+ const newPath = path.join(projectDir, 'src/app');
144
+ if (fs.existsSync(oldPath) && !fs.existsSync(newPath)) {
145
+ try { fs.renameSync(oldPath, newPath); } catch (err) {}
118
146
  }
119
147
 
120
148
  console.log(' [4/8] Authenticating with Fleetbo Cloud...');
@@ -132,7 +160,17 @@ WDS_SOCKET_PORT=0`;
132
160
  fs.writeFileSync(path.join(projectDir, '.env'), envContent, 'utf8');
133
161
 
134
162
  console.log(' [6/8] Securing environment (adding .gitignore)...');
135
- const gitignoreContent = `# Fleetbo Security\n.env\n.env.local\nnode_modules/\ndist/\nbuild/\n.DS_Store\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n`;
163
+ const gitignoreContent = `# Fleetbo Security
164
+ .env
165
+ .env.local
166
+ node_modules/
167
+ dist/
168
+ build/
169
+ .DS_Store
170
+ npm-debug.log*
171
+ yarn-debug.log*
172
+ yarn-error.log*
173
+ `;
136
174
  fs.writeFileSync(path.join(projectDir, '.gitignore'), gitignoreContent, 'utf8');
137
175
 
138
176
  const npmrcContent = `loglevel=silent\nupdate-notifier=false\n`;
@@ -140,6 +178,7 @@ WDS_SOCKET_PORT=0`;
140
178
 
141
179
  console.log(' [7/8] Installing dependencies...');
142
180
  execSync('npm install --no-audit --no-fund --silent', { stdio: 'inherit' });
181
+
143
182
  execSync('npm install cloudflared --save-dev --no-audit --no-fund --silent', { stdio: 'ignore' });
144
183
 
145
184
  console.log(' [8/8] Finalizing setup...');
@@ -147,6 +186,7 @@ WDS_SOCKET_PORT=0`;
147
186
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
148
187
  packageJson.name = projectName;
149
188
 
189
+ // Configuration pour utiliser le package NPM centralisé
150
190
  packageJson.scripts = {
151
191
  ...packageJson.scripts,
152
192
  "fleetbo": "npx -y fleetbo-cockpit-cli@latest",
@@ -158,23 +198,35 @@ WDS_SOCKET_PORT=0`;
158
198
 
159
199
  const scriptsDir = path.join(projectDir, 'scripts');
160
200
  if (fs.existsSync(scriptsDir)) {
161
- try { fs.rmSync(scriptsDir, { recursive: true, force: true }); } catch (e) {}
201
+ try {
202
+ fs.rmSync(scriptsDir, { recursive: true, force: true });
203
+ } catch (e) {
204
+ // Ignore si ça échoue
205
+ }
162
206
  }
163
207
 
208
+ // ==========================================
209
+ // 🎯 L'ANNONCE DE SUCCÈS ET LE MINI-TUTO
210
+ // ==========================================
164
211
  console.log('\n \x1b[1;32m✓ [Fleetbo] Project successfully created!\x1b[0m');
165
212
  console.log(`\n Installation path: \x1b[36m${projectDir}\x1b[0m\n`);
213
+
166
214
  console.log(' \x1b[1;33m🚀 NEXT STEPS (Mini-Tutorial):\x1b[0m');
167
215
  console.log(' --------------------------------------------------');
168
- console.log(` 1️ Navigate to your project : \x1b[36mcd ${projectName}\x1b[0m`);
169
- console.log(' 2️ Launch the Fleetbo Engine : \x1b[36mnpm run fleetbo\x1b[0m');
170
- console.log(' 3️ Summon Alex (AI Architect): \x1b[36mnpm run fleetbo alex\x1b[0m');
216
+ console.log(` 1️ Navigate to your project : \x1b[36mcd ${projectName}\x1b[0m`);
217
+ console.log(' 2️ Launch the Fleetbo Engine : \x1b[36mnpm run fleetbo\x1b[0m');
218
+ console.log(' 3️ Summon Alex (AI Architect): \x1b[36mnpm run fleetbo alex\x1b[0m');
171
219
  console.log(' --------------------------------------------------');
172
220
  console.log('\n \x1b[2mHappy coding! Build something amazing without limits.\x1b[0m\n');
221
+
222
+ console.log('');
173
223
 
174
224
  } catch (error) {
175
225
  console.error('\n Setup failed:', error.message);
176
226
  if (fs.existsSync(projectDir)) {
177
- try { fs.rmSync(projectDir, { recursive: true, force: true }); } catch(e) {}
227
+ try {
228
+ fs.rmSync(projectDir, { recursive: true, force: true });
229
+ } catch(e) {}
178
230
  }
179
231
  process.exit(1);
180
232
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fleetbo-project",
3
- "version": "1.2.97",
3
+ "version": "1.2.98",
4
4
  "description": "Creates a new Fleetbo project.",
5
5
  "main": "install-react-template.js",
6
6
  "bin": {