create-fleetbo-project 1.0.31 → 1.0.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.
@@ -10,7 +10,6 @@ const unzipper = require('unzipper');
10
10
  const repoOwner = 'FleetFleetbo';
11
11
  const repoName = 'dev.fleetbo.io';
12
12
  const branchName = 'master';
13
-
14
13
  const repoUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/${branchName}.zip`;
15
14
  const bootstrapUrl = 'https://us-central1-myapp-259bf.cloudfunctions.net/bootstrapProject';
16
15
 
@@ -25,6 +24,7 @@ if (!projectNameArg) {
25
24
  process.exit(1);
26
25
  }
27
26
 
27
+ const projectName = projectNameArg;
28
28
  const bootstrapToken = tokenArg ? tokenArg.split('=')[1] : null;
29
29
 
30
30
  if (!bootstrapToken) {
@@ -33,152 +33,86 @@ if (!bootstrapToken) {
33
33
  process.exit(1);
34
34
  }
35
35
 
36
- const projectName = projectNameArg;
37
-
38
- /**
39
- * Fonction pour copier récursivement un dossier (version robuste)
40
- */
41
- function copyRecursiveSync(src, dest) {
42
- try {
43
- const stat = fs.statSync(src);
44
-
45
- if (stat.isDirectory()) {
46
- // Créer le dossier de destination
47
- if (!fs.existsSync(dest)) {
48
- fs.mkdirSync(dest, { recursive: true });
49
- }
50
-
51
- // Copier tous les enfants
52
- const entries = fs.readdirSync(src, { withFileTypes: true });
53
- for (const entry of entries) {
54
- const srcPath = path.join(src, entry.name);
55
- const destPath = path.join(dest, entry.name);
56
-
57
- if (entry.isDirectory()) {
58
- copyRecursiveSync(srcPath, destPath);
59
- } else if (entry.isFile() || entry.isSymbolicLink()) {
60
- fs.copyFileSync(srcPath, destPath);
61
- }
62
- }
63
- } else if (stat.isFile()) {
64
- // Créer le dossier parent si nécessaire
65
- const destDir = path.dirname(dest);
66
- if (!fs.existsSync(destDir)) {
67
- fs.mkdirSync(destDir, { recursive: true });
68
- }
69
- fs.copyFileSync(src, dest);
70
- }
71
- } catch (error) {
72
- console.error(`Erreur lors de la copie de ${src} vers ${dest}:`, error.message);
73
- throw error;
74
- }
75
- }
76
-
77
36
  /**
78
37
  * Fonction pour appeler la Cloud Function et récupérer les clés.
79
38
  */
80
39
  function fetchProjectKeys(token) {
81
- return new Promise((resolve, reject) => {
82
- const postData = JSON.stringify({ token });
83
- const options = {
84
- method: 'POST',
85
- headers: {
86
- 'Content-Type': 'application/json',
87
- 'Content-Length': Buffer.byteLength(postData)
88
- }
89
- };
90
- const req = https.request(bootstrapUrl, options, (res) => {
91
- let data = '';
92
- res.on('data', (chunk) => { data += chunk; });
93
- res.on('end', () => {
94
- if (res.statusCode >= 200 && res.statusCode < 300) {
95
- resolve(JSON.parse(data));
96
- } else {
97
- const errorMsg = JSON.parse(data).error || `Erreur serveur (code: ${res.statusCode})`;
98
- reject(new Error(errorMsg));
99
- }
100
- });
101
- });
102
- req.on('error', (e) => reject(e));
103
- req.write(postData);
104
- req.end();
40
+ return new Promise((resolve, reject) => {
41
+ const postData = JSON.stringify({ token });
42
+ const options = {
43
+ method: 'POST',
44
+ headers: {
45
+ 'Content-Type': 'application/json',
46
+ 'Content-Length': Buffer.byteLength(postData)
47
+ }
48
+ };
49
+
50
+ const req = https.request(bootstrapUrl, options, (res) => {
51
+ let data = '';
52
+ res.on('data', (chunk) => { data += chunk; });
53
+ res.on('end', () => {
54
+ if (res.statusCode >= 200 && res.statusCode < 300) {
55
+ resolve(JSON.parse(data));
56
+ } else {
57
+ const errorMsg = JSON.parse(data).error || `Erreur serveur (code: ${res.statusCode})`;
58
+ reject(new Error(errorMsg));
59
+ }
60
+ });
105
61
  });
62
+
63
+ req.on('error', (e) => reject(e));
64
+ req.write(postData);
65
+ req.end();
66
+ });
106
67
  }
107
68
 
108
- /**
109
- * Fonction Principale Asynchrone
110
- */
69
+ // --- Fonction Principale Asynchrone ---
111
70
  async function setupProject() {
112
71
  console.log(`\nCréation de votre projet Fleetbo "${projectName}"...`);
113
- const projectDir = path.join(process.cwd(), projectName);
114
- const tempDir = path.join(process.cwd(), `fleetbo-temp-${Date.now()}`);
115
-
72
+
116
73
  try {
117
- // Étape 1 : Téléchargement et décompression
118
- console.log(` [1/5] 📥 Téléchargement du template...`);
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
+ });
79
+
80
+ // 2. Décompresser l'archive
81
+ console.log(' [2/4] 📦 Extraction du template...');
119
82
  await new Promise((resolve, reject) => {
120
- https.get(repoUrl, (response) => {
121
- if (response.statusCode === 301 || response.statusCode === 302) {
122
- return https.get(response.headers.location, (redirectResponse) => {
123
- redirectResponse.pipe(unzipper.Extract({ path: tempDir }))
124
- .on('close', () => setTimeout(resolve, 1000))
125
- .on('error', reject);
126
- }).on('error', reject);
127
- }
128
- response.pipe(unzipper.Extract({ path: tempDir }))
129
- .on('close', () => setTimeout(resolve, 1000))
130
- .on('error', reject);
131
- }).on('error', reject);
83
+ response.pipe(unzipper.Extract({ path: '.' }))
84
+ .on('finish', resolve)
85
+ .on('error', reject);
132
86
  });
133
-
134
- console.log(' [2/5] ✅ Template téléchargé. Vérification...');
135
-
136
- // Vérifier que l'extraction est complète
137
- if (!fs.existsSync(tempDir) || fs.readdirSync(tempDir).length === 0) {
138
- throw new Error('Le téléchargement ou l\'extraction a échoué');
139
- }
140
87
 
141
- // Étape 2 : Localiser intelligemment la racine du projet
142
- const unzippedBaseFolder = fs.readdirSync(tempDir)[0];
143
- let sourceDir = path.join(tempDir, unzippedBaseFolder);
144
-
145
- if (!fs.existsSync(path.join(sourceDir, 'package.json'))) {
146
- const nestedProjectDir = fs.readdirSync(sourceDir).find(file => {
147
- const fullPath = path.join(sourceDir, file);
148
- return fs.statSync(fullPath).isDirectory() && fs.existsSync(path.join(fullPath, 'package.json'));
149
- });
150
- if (!nestedProjectDir) throw new Error('Impossible de trouver package.json dans le template.');
151
- sourceDir = path.join(sourceDir, nestedProjectDir);
152
- }
153
-
154
- // Étape 3 : Copier RÉCURSIVEMENT tous les fichiers et dossiers
155
- console.log(` [3/5] 📂 Copie de la structure complète du projet...`);
156
- copyRecursiveSync(sourceDir, projectDir);
157
-
158
- // Étape 4 : Récupération des clés
159
- console.log(' [4/5] 🔑 Récupération des clés de projet...');
88
+ // Le dossier décompressé aura un nom comme "dev.fleetbo.io-master", on le renomme
89
+ fs.renameSync(`${repoName}-${branchName}`, projectName);
90
+
91
+ // 3. Récupérer les clés du projet
92
+ console.log(' [3/4] 🔑 Récupération des clés de projet...');
160
93
  const keys = await fetchProjectKeys(bootstrapToken);
161
94
 
162
95
  if (!keys.enterpriseId || !keys.fleetboDBKey) {
163
- throw new Error("Les clés reçues du serveur sont invalides.");
96
+ throw new Error("Les clés reçues du serveur sont invalides.");
164
97
  }
165
98
 
166
- // Configuration du fichier .env
99
+ // 4. Configurer le fichier .env
167
100
  const envContent = `REACT_APP_FLEETBO_DB_KEY=${keys.fleetboDBKey}\nREACT_APP_ENTERPRISE_ID=${keys.enterpriseId}\n`;
168
- fs.writeFileSync(path.join(projectDir, '.env'), envContent, 'utf8');
101
+ fs.writeFileSync(path.join(projectName, '.env'), envContent, 'utf8');
169
102
  console.log(' ✅ Fichier .env configuré avec succès.');
170
103
 
171
- // Mise à jour du package.json avec le nom du projet
172
- const packageJsonPath = path.join(projectDir, 'package.json');
104
+ // 5. Se déplacer dans le nouveau dossier et installer les dépendances
105
+ process.chdir(projectName);
106
+
107
+ console.log(' [4/4] 📦 Installation des dépendances...');
108
+ execSync('npm install', { stdio: 'inherit' });
109
+
110
+ // 6. Mettre à jour le package.json avec le nom du projet
111
+ const packageJsonPath = path.join(process.cwd(), 'package.json');
173
112
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
174
113
  packageJson.name = projectName;
175
114
  fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8');
176
115
 
177
- // Étape 5 : Installation des dépendances
178
- console.log(' [5/5] 📦 Installation des dépendances...');
179
- process.chdir(projectDir);
180
- execSync('npm install', { stdio: 'inherit' });
181
-
182
116
  console.log('\n🚀 Votre projet Fleetbo est prêt !');
183
117
  console.log(`\nPour commencer, exécutez les commandes suivantes :`);
184
118
  console.log(` cd ${projectName}`);
@@ -186,22 +120,12 @@ async function setupProject() {
186
120
 
187
121
  } catch (error) {
188
122
  console.error('\n❌ Une erreur est survenue lors de la création du projet :', error.message);
189
- console.error(' Détails:', error);
190
123
 
191
- // NE PAS nettoyer le projectDir si on veut déboguer
192
- // Commenter cette section pour garder les fichiers et voir ce qui manque
193
- if (fs.existsSync(projectDir)) {
194
- console.log(' 🧹 Nettoyage du projet incomplet...');
195
- fs.rmSync(projectDir, { recursive: true, force: true });
124
+ // Nettoyer en cas d'erreur
125
+ if (fs.existsSync(projectName)) {
126
+ fs.rmSync(projectName, { recursive: true, force: true });
196
127
  }
197
128
  process.exit(1);
198
- } finally {
199
- // Nettoyer APRÈS que tout soit terminé
200
- setTimeout(() => {
201
- if (fs.existsSync(tempDir)) {
202
- fs.rmSync(tempDir, { recursive: true, force: true });
203
- }
204
- }, 2000);
205
129
  }
206
130
  }
207
131
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fleetbo-project",
3
- "version": "1.0.31",
3
+ "version": "1.0.32",
4
4
  "description": "Creates a new Fleetbo project.",
5
5
  "main": "install-react-template.js",
6
6
  "bin": {