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.
- package/install-react-template.js +59 -135
- package/package.json +1 -1
|
@@ -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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
114
|
-
const tempDir = path.join(process.cwd(), `fleetbo-temp-${Date.now()}`);
|
|
115
|
-
|
|
72
|
+
|
|
116
73
|
try {
|
|
117
|
-
//
|
|
118
|
-
console.log(
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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
|
-
//
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
96
|
+
throw new Error("Les clés reçues du serveur sont invalides.");
|
|
164
97
|
}
|
|
165
98
|
|
|
166
|
-
//
|
|
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(
|
|
101
|
+
fs.writeFileSync(path.join(projectName, '.env'), envContent, 'utf8');
|
|
169
102
|
console.log(' ✅ Fichier .env configuré avec succès.');
|
|
170
103
|
|
|
171
|
-
//
|
|
172
|
-
|
|
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
|
-
//
|
|
192
|
-
|
|
193
|
-
|
|
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
|
|