create-fleetbo-project 1.0.32 → 1.0.34
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 +97 -65
- package/package.json +1 -1
|
@@ -6,11 +6,23 @@ const path = require('path');
|
|
|
6
6
|
const https = require('https');
|
|
7
7
|
const unzipper = require('unzipper');
|
|
8
8
|
|
|
9
|
+
// --- Vérification de la version de Node.js ---
|
|
10
|
+
const [major, minor] = process.versions.node.split('.').map(parseFloat);
|
|
11
|
+
if (major < 16 || (major === 16 && minor < 7)) {
|
|
12
|
+
console.error(`\n❌ Erreur : Ce script requiert Node.js v16.7.0 ou une version supérieure pour fonctionner correctement.`);
|
|
13
|
+
console.error(` Votre version actuelle est ${process.versions.node}.`);
|
|
14
|
+
console.log(` Veuillez mettre à jour votre installation de Node.js.`);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
9
18
|
// --- Configuration ---
|
|
10
|
-
const repoOwner = 'FleetFleetbo';
|
|
11
|
-
const repoName = 'dev.fleetbo.io';
|
|
12
|
-
const branchName = 'master';
|
|
19
|
+
const repoOwner = 'FleetFleetbo'; // Assurez-vous que c'est le bon nom d'utilisateur GitHub
|
|
20
|
+
const repoName = 'dev.fleetbo.io'; // Assurez-vous que c'est le bon nom de dépôt
|
|
21
|
+
const branchName = 'master'; // Le nom de la branche est maintenant configurable
|
|
22
|
+
|
|
13
23
|
const repoUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/${branchName}.zip`;
|
|
24
|
+
|
|
25
|
+
// URL de votre Cloud Function.
|
|
14
26
|
const bootstrapUrl = 'https://us-central1-myapp-259bf.cloudfunctions.net/bootstrapProject';
|
|
15
27
|
|
|
16
28
|
// --- Analyse des Arguments ---
|
|
@@ -24,7 +36,6 @@ if (!projectNameArg) {
|
|
|
24
36
|
process.exit(1);
|
|
25
37
|
}
|
|
26
38
|
|
|
27
|
-
const projectName = projectNameArg;
|
|
28
39
|
const bootstrapToken = tokenArg ? tokenArg.split('=')[1] : null;
|
|
29
40
|
|
|
30
41
|
if (!bootstrapToken) {
|
|
@@ -33,82 +44,101 @@ if (!bootstrapToken) {
|
|
|
33
44
|
process.exit(1);
|
|
34
45
|
}
|
|
35
46
|
|
|
47
|
+
const projectName = projectNameArg;
|
|
48
|
+
|
|
36
49
|
/**
|
|
37
50
|
* Fonction pour appeler la Cloud Function et récupérer les clés.
|
|
38
51
|
*/
|
|
39
52
|
function fetchProjectKeys(token) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
const postData = JSON.stringify({ token });
|
|
55
|
+
const options = { method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) } };
|
|
56
|
+
const req = https.request(bootstrapUrl, options, (res) => {
|
|
57
|
+
let data = '';
|
|
58
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
59
|
+
res.on('end', () => {
|
|
60
|
+
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
61
|
+
try {
|
|
62
|
+
resolve(JSON.parse(data));
|
|
63
|
+
} catch (e) {
|
|
64
|
+
reject(new Error('Réponse invalide du serveur de clés.'));
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
const errorMsg = JSON.parse(data).error || `Erreur serveur (code: ${res.statusCode})`;
|
|
68
|
+
reject(new Error(errorMsg));
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
req.on('error', (e) => reject(e));
|
|
73
|
+
req.write(postData);
|
|
74
|
+
req.end();
|
|
61
75
|
});
|
|
62
|
-
|
|
63
|
-
req.on('error', (e) => reject(e));
|
|
64
|
-
req.write(postData);
|
|
65
|
-
req.end();
|
|
66
|
-
});
|
|
67
76
|
}
|
|
68
77
|
|
|
69
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Fonction Principale Asynchrone (Version pro avec téléchargement direct et gestion de fichiers robuste)
|
|
80
|
+
*/
|
|
70
81
|
async function setupProject() {
|
|
71
82
|
console.log(`\nCréation de votre projet Fleetbo "${projectName}"...`);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
// 1. Télécharger le template depuis GitHub
|
|
75
|
-
console.log(' [1/4] 📥 Téléchargement du template...');
|
|
76
|
-
const response = await new Promise((resolve, reject) => {
|
|
77
|
-
https.get(repoUrl, res => resolve(res)).on('error', err => reject(err));
|
|
78
|
-
});
|
|
83
|
+
const projectDir = path.join(process.cwd(), projectName);
|
|
84
|
+
const tempDir = path.join(process.cwd(), `fleetbo-temp-${Date.now()}`);
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
|
|
86
|
+
try {
|
|
87
|
+
// Étape 1 : Téléchargement et décompression
|
|
88
|
+
console.log(` [1/5] 📥 Téléchargement du template...`);
|
|
82
89
|
await new Promise((resolve, reject) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
https.get(repoUrl, (response) => {
|
|
91
|
+
if (response.statusCode === 301 || response.statusCode === 302) {
|
|
92
|
+
return https.get(response.headers.location, (redirectResponse) => {
|
|
93
|
+
redirectResponse.pipe(unzipper.Extract({ path: tempDir }))
|
|
94
|
+
.on('finish', resolve)
|
|
95
|
+
.on('error', (err) => reject(new Error(`Erreur de décompression: ${err.message}`)));
|
|
96
|
+
}).on('error', (err) => reject(new Error(`Erreur réseau après redirection: ${err.message}`)));
|
|
97
|
+
}
|
|
98
|
+
if (response.statusCode !== 200) {
|
|
99
|
+
return reject(new Error(`Échec du téléchargement. Statut: ${response.statusCode}`));
|
|
100
|
+
}
|
|
101
|
+
response.pipe(unzipper.Extract({ path: tempDir }))
|
|
102
|
+
.on('finish', resolve)
|
|
103
|
+
.on('error', (err) => reject(new Error(`Erreur de décompression: ${err.message}`)));
|
|
104
|
+
}).on('error', (err) => reject(new Error(`Erreur réseau: ${err.message}`)));
|
|
86
105
|
});
|
|
106
|
+
console.log(' [2/5] ✅ Template téléchargé. Organisation des fichiers...');
|
|
87
107
|
|
|
88
|
-
//
|
|
89
|
-
fs.
|
|
90
|
-
|
|
91
|
-
// 3. Récupérer les clés du projet
|
|
92
|
-
console.log(' [3/4] 🔑 Récupération des clés de projet...');
|
|
93
|
-
const keys = await fetchProjectKeys(bootstrapToken);
|
|
108
|
+
// Étape 2 bis : Localiser la racine du projet dans le dossier décompressé
|
|
109
|
+
const unzippedBaseFolder = fs.readdirSync(tempDir)[0];
|
|
110
|
+
let sourceDir = path.join(tempDir, unzippedBaseFolder);
|
|
94
111
|
|
|
112
|
+
if (!fs.existsSync(path.join(sourceDir, 'package.json'))) {
|
|
113
|
+
const nestedProjectDir = fs.readdirSync(sourceDir).find(file => {
|
|
114
|
+
const fullPath = path.join(sourceDir, file);
|
|
115
|
+
return fs.statSync(fullPath).isDirectory() && fs.existsSync(path.join(fullPath, 'package.json'));
|
|
116
|
+
});
|
|
117
|
+
if (!nestedProjectDir) throw new Error('Impossible de trouver le fichier package.json dans le template téléchargé.');
|
|
118
|
+
sourceDir = path.join(sourceDir, nestedProjectDir);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Étape 2 ter : Copier les fichiers vers la destination finale
|
|
122
|
+
fs.mkdirSync(projectDir, { recursive: true });
|
|
123
|
+
for (const file of fs.readdirSync(sourceDir)) {
|
|
124
|
+
fs.cpSync(path.join(sourceDir, file), path.join(projectDir, file), { recursive: true });
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
process.chdir(projectDir);
|
|
128
|
+
console.log(' [3/5] 🔑 Récupération des clés de projet...');
|
|
129
|
+
const keys = await fetchProjectKeys(bootstrapToken);
|
|
95
130
|
if (!keys.enterpriseId || !keys.fleetboDBKey) {
|
|
96
|
-
|
|
131
|
+
throw new Error("Les clés reçues du serveur sont invalides.");
|
|
97
132
|
}
|
|
98
133
|
|
|
99
|
-
|
|
134
|
+
console.log(' [4/5] ✅ Fichier .env configuré avec succès.');
|
|
100
135
|
const envContent = `REACT_APP_FLEETBO_DB_KEY=${keys.fleetboDBKey}\nREACT_APP_ENTERPRISE_ID=${keys.enterpriseId}\n`;
|
|
101
|
-
fs.writeFileSync(path.join(
|
|
102
|
-
console.log(' ✅ Fichier .env configuré avec succès.');
|
|
136
|
+
fs.writeFileSync(path.join(projectDir, '.env'), envContent, 'utf8');
|
|
103
137
|
|
|
104
|
-
|
|
105
|
-
process.chdir(projectName);
|
|
106
|
-
|
|
107
|
-
console.log(' [4/4] 📦 Installation des dépendances...');
|
|
138
|
+
console.log(' [5/5] 📦 Installation des dépendances...');
|
|
108
139
|
execSync('npm install', { stdio: 'inherit' });
|
|
109
140
|
|
|
110
|
-
|
|
111
|
-
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
141
|
+
const packageJsonPath = path.join(projectDir, 'package.json');
|
|
112
142
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
113
143
|
packageJson.name = projectName;
|
|
114
144
|
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8');
|
|
@@ -120,13 +150,15 @@ async function setupProject() {
|
|
|
120
150
|
|
|
121
151
|
} catch (error) {
|
|
122
152
|
console.error('\n❌ Une erreur est survenue lors de la création du projet :', error.message);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
153
|
+
if (fs.existsSync(projectDir)) {
|
|
154
|
+
fs.rmSync(projectDir, { recursive: true, force: true });
|
|
155
|
+
}
|
|
156
|
+
} finally {
|
|
157
|
+
if (fs.existsSync(tempDir)) {
|
|
158
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
127
159
|
}
|
|
128
|
-
process.exit(1);
|
|
129
160
|
}
|
|
130
161
|
}
|
|
131
162
|
|
|
132
|
-
setupProject();
|
|
163
|
+
setupProject();
|
|
164
|
+
|