create-fleetbo-project 1.2.95 → 1.2.97
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 +50 -83
- package/package.json +2 -2
|
@@ -1,59 +1,68 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
process.stdout.write("\x1b[1A\x1b[2K".repeat(4));
|
|
4
|
+
console.clear();
|
|
5
|
+
|
|
3
6
|
const { execSync } = require('child_process');
|
|
4
7
|
const fs = require('fs');
|
|
5
8
|
const path = require('path');
|
|
6
9
|
const https = require('https');
|
|
7
10
|
|
|
8
|
-
const repoOwner = 'FleetFleetbo';
|
|
9
|
-
const repoName = 'dev.fleetbo.io';
|
|
10
|
-
const branchName = 'master';
|
|
11
|
-
const archiveUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/${branchName}.tar.gz`;
|
|
12
11
|
const bootstrapUrl = 'https://us-central1-myapp-259bf.cloudfunctions.net/bootstrapProject';
|
|
13
12
|
|
|
14
13
|
const args = process.argv.slice(2);
|
|
15
14
|
const projectNameArg = args.find(arg => !arg.startsWith('--'));
|
|
16
15
|
const tokenArg = args.find(arg => arg.startsWith('--token='));
|
|
17
16
|
const emailArg = args.find(arg => arg.startsWith('--email='));
|
|
17
|
+
const frameworkArg = args.find(arg => arg.startsWith('--framework='));
|
|
18
|
+
|
|
18
19
|
const bootstrapTokenArg = tokenArg ? tokenArg.split('=')[1] : null;
|
|
19
20
|
const userEmailArg = emailArg ? emailArg.split('=')[1] : null;
|
|
21
|
+
const framework = frameworkArg ? frameworkArg.split('=')[1].toLowerCase() : 'react';
|
|
20
22
|
|
|
21
23
|
if (!projectNameArg || !bootstrapTokenArg || !userEmailArg) {
|
|
22
|
-
console.error('\n Usage: npx create-fleetbo-project <name> --token=<token> --email=<email>');
|
|
24
|
+
console.error('\n Usage: npx create-fleetbo-project <name> --token=<token> --email=<email> [--framework=react|vue]');
|
|
23
25
|
process.exit(1);
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
const projectName = projectNameArg;
|
|
27
29
|
const projectDir = path.join(process.cwd(), projectName);
|
|
28
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...`);
|
|
35
|
+
try {
|
|
36
|
+
archiveUrl = execSync('npm view my-fleetbo-vue dist.tarball', { stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim();
|
|
37
|
+
} catch (e) {
|
|
38
|
+
console.error('\n ❌ Error: Could not locate "my-fleetbo-vue" on npm.');
|
|
39
|
+
process.exit(1);
|
|
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
|
+
}
|
|
47
|
+
|
|
29
48
|
function fetchProjectKeys(token) {
|
|
30
49
|
return new Promise((resolve, reject) => {
|
|
31
50
|
const postData = JSON.stringify({ token });
|
|
32
51
|
const uri = new URL(bootstrapUrl);
|
|
33
52
|
const options = {
|
|
34
|
-
hostname: uri.hostname,
|
|
35
|
-
|
|
36
|
-
method: 'POST',
|
|
37
|
-
headers: {
|
|
38
|
-
'Content-Type': 'application/json',
|
|
39
|
-
'Content-Length': Buffer.byteLength(postData)
|
|
40
|
-
}
|
|
53
|
+
hostname: uri.hostname, path: uri.pathname, method: 'POST',
|
|
54
|
+
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) }
|
|
41
55
|
};
|
|
42
56
|
const req = https.request(options, (res) => {
|
|
43
57
|
let data = '';
|
|
44
58
|
res.on('data', (chunk) => { data += chunk; });
|
|
45
59
|
res.on('end', () => {
|
|
46
60
|
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
47
|
-
try { resolve(JSON.parse(data)); }
|
|
48
|
-
|
|
49
|
-
} else {
|
|
50
|
-
reject(new Error(`Server error ${res.statusCode}`));
|
|
51
|
-
}
|
|
61
|
+
try { resolve(JSON.parse(data)); } catch (e) { reject(new Error('Invalid response')); }
|
|
62
|
+
} else { reject(new Error(`Server error ${res.statusCode}`)); }
|
|
52
63
|
});
|
|
53
64
|
});
|
|
54
|
-
req.on('error', (e) => reject(e));
|
|
55
|
-
req.write(postData);
|
|
56
|
-
req.end();
|
|
65
|
+
req.on('error', (e) => reject(e)); req.write(postData); req.end();
|
|
57
66
|
});
|
|
58
67
|
}
|
|
59
68
|
|
|
@@ -61,46 +70,30 @@ function downloadEngine(url, dest) {
|
|
|
61
70
|
return new Promise((resolve, reject) => {
|
|
62
71
|
const uri = new URL(url);
|
|
63
72
|
const options = {
|
|
64
|
-
hostname: uri.hostname,
|
|
65
|
-
|
|
66
|
-
method: 'GET',
|
|
67
|
-
headers: {
|
|
68
|
-
'User-Agent': 'Fleetbo-CLI-Installer',
|
|
69
|
-
'Accept': '*/*'
|
|
70
|
-
}
|
|
73
|
+
hostname: uri.hostname, path: uri.pathname + uri.search, method: 'GET',
|
|
74
|
+
headers: { 'User-Agent': 'Fleetbo-CLI-Installer', 'Accept': '*/*' }
|
|
71
75
|
};
|
|
72
76
|
const request = https.get(options, (response) => {
|
|
73
77
|
if (response.statusCode === 301 || response.statusCode === 302) {
|
|
74
|
-
if (!response.headers.location) {
|
|
75
|
-
reject(new Error("Redirect error"));
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
+
if (!response.headers.location) { reject(new Error("Redirect error")); return; }
|
|
78
79
|
downloadEngine(response.headers.location, dest).then(resolve).catch(reject);
|
|
79
80
|
return;
|
|
80
81
|
}
|
|
81
|
-
if (response.statusCode !== 200) {
|
|
82
|
-
reject(new Error(`Status: ${response.statusCode}`));
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
82
|
+
if (response.statusCode !== 200) { reject(new Error(`Status: ${response.statusCode}`)); return; }
|
|
85
83
|
const file = fs.createWriteStream(dest);
|
|
86
84
|
response.pipe(file);
|
|
87
85
|
file.on('finish', () => file.close(resolve));
|
|
88
|
-
file.on('error', (err) => {
|
|
89
|
-
fs.unlink(dest, () => {});
|
|
90
|
-
reject(err);
|
|
91
|
-
});
|
|
86
|
+
file.on('error', (err) => { fs.unlink(dest, () => {}); reject(err); });
|
|
92
87
|
});
|
|
93
88
|
request.on('error', (err) => reject(err));
|
|
94
89
|
});
|
|
95
90
|
}
|
|
96
91
|
|
|
97
92
|
async function setupProject() {
|
|
98
|
-
console.log(`\n ⚡ Initializing Fleetbo Framework for "${projectName}"...`);
|
|
93
|
+
console.log(`\n ⚡ Initializing Fleetbo Framework (\x1b[36m${framework.toUpperCase()}\x1b[0m) for "${projectName}"...`);
|
|
99
94
|
|
|
100
95
|
try {
|
|
101
|
-
if (fs.existsSync(projectDir)) {
|
|
102
|
-
throw new Error(`Directory "${projectName}" already exists.`);
|
|
103
|
-
}
|
|
96
|
+
if (fs.existsSync(projectDir)) { throw new Error(`Directory "${projectName}" already exists.`); }
|
|
104
97
|
fs.mkdirSync(projectDir);
|
|
105
98
|
|
|
106
99
|
console.log(' [1/8] Downloading Fleetbo Core Engine...');
|
|
@@ -111,19 +104,17 @@ async function setupProject() {
|
|
|
111
104
|
try {
|
|
112
105
|
execSync(`tar -xf "${archivePath}" -C "${projectDir}" --strip-components=1`, { stdio: 'ignore' });
|
|
113
106
|
fs.unlinkSync(archivePath);
|
|
114
|
-
} catch (e) {
|
|
115
|
-
throw new Error("Extract failed.");
|
|
116
|
-
}
|
|
107
|
+
} catch (e) { throw new Error("Extract failed."); }
|
|
117
108
|
|
|
118
109
|
process.chdir(projectDir);
|
|
119
110
|
|
|
120
|
-
console.log(' [3/8] Standardizing Architecture
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
+
}
|
|
127
118
|
}
|
|
128
119
|
|
|
129
120
|
console.log(' [4/8] Authenticating with Fleetbo Cloud...');
|
|
@@ -141,17 +132,7 @@ WDS_SOCKET_PORT=0`;
|
|
|
141
132
|
fs.writeFileSync(path.join(projectDir, '.env'), envContent, 'utf8');
|
|
142
133
|
|
|
143
134
|
console.log(' [6/8] Securing environment (adding .gitignore)...');
|
|
144
|
-
const gitignoreContent = `# Fleetbo Security
|
|
145
|
-
.env
|
|
146
|
-
.env.local
|
|
147
|
-
node_modules/
|
|
148
|
-
dist/
|
|
149
|
-
build/
|
|
150
|
-
.DS_Store
|
|
151
|
-
npm-debug.log*
|
|
152
|
-
yarn-debug.log*
|
|
153
|
-
yarn-error.log*
|
|
154
|
-
`;
|
|
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`;
|
|
155
136
|
fs.writeFileSync(path.join(projectDir, '.gitignore'), gitignoreContent, 'utf8');
|
|
156
137
|
|
|
157
138
|
const npmrcContent = `loglevel=silent\nupdate-notifier=false\n`;
|
|
@@ -159,7 +140,6 @@ yarn-error.log*
|
|
|
159
140
|
|
|
160
141
|
console.log(' [7/8] Installing dependencies...');
|
|
161
142
|
execSync('npm install --no-audit --no-fund --silent', { stdio: 'inherit' });
|
|
162
|
-
|
|
163
143
|
execSync('npm install cloudflared --save-dev --no-audit --no-fund --silent', { stdio: 'ignore' });
|
|
164
144
|
|
|
165
145
|
console.log(' [8/8] Finalizing setup...');
|
|
@@ -167,7 +147,6 @@ yarn-error.log*
|
|
|
167
147
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
168
148
|
packageJson.name = projectName;
|
|
169
149
|
|
|
170
|
-
// Configuration pour utiliser le package NPM centralisé
|
|
171
150
|
packageJson.scripts = {
|
|
172
151
|
...packageJson.scripts,
|
|
173
152
|
"fleetbo": "npx -y fleetbo-cockpit-cli@latest",
|
|
@@ -179,35 +158,23 @@ yarn-error.log*
|
|
|
179
158
|
|
|
180
159
|
const scriptsDir = path.join(projectDir, 'scripts');
|
|
181
160
|
if (fs.existsSync(scriptsDir)) {
|
|
182
|
-
try {
|
|
183
|
-
fs.rmSync(scriptsDir, { recursive: true, force: true });
|
|
184
|
-
} catch (e) {
|
|
185
|
-
// Ignore si ça échoue
|
|
186
|
-
}
|
|
161
|
+
try { fs.rmSync(scriptsDir, { recursive: true, force: true }); } catch (e) {}
|
|
187
162
|
}
|
|
188
163
|
|
|
189
|
-
// ==========================================
|
|
190
|
-
// 🎯 L'ANNONCE DE SUCCÈS ET LE MINI-TUTO
|
|
191
|
-
// ==========================================
|
|
192
164
|
console.log('\n \x1b[1;32m✓ [Fleetbo] Project successfully created!\x1b[0m');
|
|
193
165
|
console.log(`\n Installation path: \x1b[36m${projectDir}\x1b[0m\n`);
|
|
194
|
-
|
|
195
166
|
console.log(' \x1b[1;33m🚀 NEXT STEPS (Mini-Tutorial):\x1b[0m');
|
|
196
167
|
console.log(' --------------------------------------------------');
|
|
197
|
-
console.log(` 1️
|
|
198
|
-
console.log(' 2️
|
|
199
|
-
console.log(' 3️
|
|
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');
|
|
200
171
|
console.log(' --------------------------------------------------');
|
|
201
172
|
console.log('\n \x1b[2mHappy coding! Build something amazing without limits.\x1b[0m\n');
|
|
202
|
-
|
|
203
|
-
console.log('');
|
|
204
173
|
|
|
205
174
|
} catch (error) {
|
|
206
175
|
console.error('\n Setup failed:', error.message);
|
|
207
176
|
if (fs.existsSync(projectDir)) {
|
|
208
|
-
try {
|
|
209
|
-
fs.rmSync(projectDir, { recursive: true, force: true });
|
|
210
|
-
} catch(e) {}
|
|
177
|
+
try { fs.rmSync(projectDir, { recursive: true, force: true }); } catch(e) {}
|
|
211
178
|
}
|
|
212
179
|
process.exit(1);
|
|
213
180
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-fleetbo-project",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.97",
|
|
4
4
|
"description": "Creates a new Fleetbo project.",
|
|
5
5
|
"main": "install-react-template.js",
|
|
6
6
|
"bin": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"fullstack",
|
|
23
23
|
"OS",
|
|
24
24
|
"Cloud",
|
|
25
|
-
"
|
|
25
|
+
"Mobile"
|
|
26
26
|
],
|
|
27
27
|
"author": "Jean Aubain NOUCTI",
|
|
28
28
|
"license": "ISC"
|