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