create-fleetbo-project 1.0.31 → 1.0.33

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.
@@ -7,11 +7,13 @@ const https = require('https');
7
7
  const unzipper = require('unzipper');
8
8
 
9
9
  // --- Configuration ---
10
- const repoOwner = 'FleetFleetbo';
11
- const repoName = 'dev.fleetbo.io';
12
- const branchName = 'master';
10
+ const repoOwner = 'FleetFleetbo'; // Assurez-vous que c'est le bon nom d'utilisateur GitHub
11
+ const repoName = 'dev.fleetbo.io'; // Assurez-vous que c'est le bon nom de dépôt
12
+ const branchName = 'master'; // Le nom de la branche est maintenant configurable
13
13
 
14
14
  const repoUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/${branchName}.zip`;
15
+
16
+ // URL de votre Cloud Function.
15
17
  const bootstrapUrl = 'https://us-central1-myapp-259bf.cloudfunctions.net/bootstrapProject';
16
18
 
17
19
  // --- Analyse des Arguments ---
@@ -35,58 +37,13 @@ if (!bootstrapToken) {
35
37
 
36
38
  const projectName = projectNameArg;
37
39
 
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
40
  /**
78
41
  * Fonction pour appeler la Cloud Function et récupérer les clés.
79
42
  */
80
43
  function fetchProjectKeys(token) {
81
44
  return new Promise((resolve, reject) => {
82
45
  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
- };
46
+ const options = { method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) } };
90
47
  const req = https.request(bootstrapUrl, options, (res) => {
91
48
  let data = '';
92
49
  res.on('data', (chunk) => { data += chunk; });
@@ -106,7 +63,7 @@ function fetchProjectKeys(token) {
106
63
  }
107
64
 
108
65
  /**
109
- * Fonction Principale Asynchrone
66
+ * Fonction Principale Asynchrone (Version pro avec téléchargement direct et gestion de fichiers robuste)
110
67
  */
111
68
  async function setupProject() {
112
69
  console.log(`\nCréation de votre projet Fleetbo "${projectName}"...`);
@@ -119,66 +76,66 @@ async function setupProject() {
119
76
  await new Promise((resolve, reject) => {
120
77
  https.get(repoUrl, (response) => {
121
78
  if (response.statusCode === 301 || response.statusCode === 302) {
79
+ // Gérer la redirection
122
80
  return https.get(response.headers.location, (redirectResponse) => {
123
81
  redirectResponse.pipe(unzipper.Extract({ path: tempDir }))
124
- .on('close', () => setTimeout(resolve, 1000))
125
- .on('error', reject);
126
- }).on('error', reject);
82
+ .on('finish', resolve)
83
+ .on('error', (err) => reject(new Error(`Erreur de décompression: ${err.message}`)));
84
+ }).on('error', (err) => reject(new Error(`Erreur réseau après redirection: ${err.message}`)));
85
+ }
86
+ if (response.statusCode !== 200) {
87
+ return reject(new Error(`Échec du téléchargement. Statut: ${response.statusCode}`));
127
88
  }
128
89
  response.pipe(unzipper.Extract({ path: tempDir }))
129
- .on('close', () => setTimeout(resolve, 1000))
130
- .on('error', reject);
131
- }).on('error', reject);
90
+ .on('finish', resolve)
91
+ .on('error', (err) => reject(new Error(`Erreur de décompression: ${err.message}`)));
92
+ }).on('error', (err) => reject(new Error(`Erreur réseau: ${err.message}`)));
132
93
  });
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
- }
94
+ console.log(' [2/5] ✅ Template téléchargé. Organisation des fichiers...');
140
95
 
141
- // Étape 2 : Localiser intelligemment la racine du projet
96
+ // Étape 2 bis : Localiser intelligemment la racine du projet dans le dossier décompressé
142
97
  const unzippedBaseFolder = fs.readdirSync(tempDir)[0];
143
98
  let sourceDir = path.join(tempDir, unzippedBaseFolder);
144
99
 
100
+ // Gère le cas où le projet est dans un sous-dossier du repo
145
101
  if (!fs.existsSync(path.join(sourceDir, 'package.json'))) {
146
102
  const nestedProjectDir = fs.readdirSync(sourceDir).find(file => {
147
103
  const fullPath = path.join(sourceDir, file);
148
104
  return fs.statSync(fullPath).isDirectory() && fs.existsSync(path.join(fullPath, 'package.json'));
149
105
  });
150
- if (!nestedProjectDir) throw new Error('Impossible de trouver package.json dans le template.');
106
+ if (!nestedProjectDir) throw new Error('Impossible de trouver le fichier package.json dans le template téléchargé.');
151
107
  sourceDir = path.join(sourceDir, nestedProjectDir);
152
108
  }
153
109
 
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);
110
+ // Étape 2 ter : Copier les fichiers vers la destination finale
111
+ fs.mkdirSync(projectDir, { recursive: true });
112
+ // **CORRECTION :** Utilisation de `fs.cpSync` pour copier récursivement chaque élément.
113
+ // C'est une méthode plus fiable pour s'assurer que toute l'arborescence
114
+ // des fichiers (y compris le contenu de /src) est copiée à l'identique.
115
+ for (const file of fs.readdirSync(sourceDir)) {
116
+ fs.cpSync(path.join(sourceDir, file), path.join(projectDir, file), { recursive: true });
117
+ }
157
118
 
158
- // Étape 4 : Récupération des clés
159
- console.log(' [4/5] 🔑 Récupération des clés de projet...');
119
+ process.chdir(projectDir);
120
+ console.log(' [3/5] 🔑 Récupération des clés de projet...');
160
121
  const keys = await fetchProjectKeys(bootstrapToken);
161
-
162
122
  if (!keys.enterpriseId || !keys.fleetboDBKey) {
163
123
  throw new Error("Les clés reçues du serveur sont invalides.");
164
124
  }
165
125
 
166
- // Configuration du fichier .env
126
+ console.log(' [4/5] Fichier .env configuré avec succès.');
167
127
  const envContent = `REACT_APP_FLEETBO_DB_KEY=${keys.fleetboDBKey}\nREACT_APP_ENTERPRISE_ID=${keys.enterpriseId}\n`;
168
128
  fs.writeFileSync(path.join(projectDir, '.env'), envContent, 'utf8');
169
- console.log(' ✅ Fichier .env configuré avec succès.');
170
129
 
171
- // Mise à jour du package.json avec le nom du projet
130
+ console.log(' [5/5] 📦 Installation des dépendances...');
131
+ execSync('npm install', { stdio: 'inherit' });
132
+
133
+ // Personnalisation du nom du projet dans package.json
172
134
  const packageJsonPath = path.join(projectDir, 'package.json');
173
135
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
174
136
  packageJson.name = projectName;
175
137
  fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8');
176
138
 
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
139
  console.log('\n🚀 Votre projet Fleetbo est prêt !');
183
140
  console.log(`\nPour commencer, exécutez les commandes suivantes :`);
184
141
  console.log(` cd ${projectName}`);
@@ -186,23 +143,15 @@ async function setupProject() {
186
143
 
187
144
  } catch (error) {
188
145
  console.error('\n❌ Une erreur est survenue lors de la création du projet :', error.message);
189
- console.error(' Détails:', error);
190
-
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
146
  if (fs.existsSync(projectDir)) {
194
- console.log(' 🧹 Nettoyage du projet incomplet...');
195
147
  fs.rmSync(projectDir, { recursive: true, force: true });
196
148
  }
197
- process.exit(1);
198
149
  } 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);
150
+ // Nettoyage du dossier temporaire
151
+ if (fs.existsSync(tempDir)) {
152
+ fs.rmSync(tempDir, { recursive: true, force: true });
153
+ }
205
154
  }
206
155
  }
207
156
 
208
- setupProject();
157
+ setupProject();
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.33",
4
4
  "description": "Creates a new Fleetbo project.",
5
5
  "main": "install-react-template.js",
6
6
  "bin": {