@configjs/cli 1.1.4 → 1.1.6
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/README.fr.md +1 -1
- package/README.md +16 -2
- package/dist/{check-XDGAGYOE.js → check-AJ4GD66M.js} +6 -5
- package/dist/chunk-3NRMV3WL.js +569 -0
- package/dist/chunk-HM2JWJOO.js +418 -0
- package/dist/{chunk-OAAGGK2H.js → chunk-JTTIDBSN.js} +361 -317
- package/dist/chunk-MQV3WNMH.js +114 -0
- package/dist/chunk-QBMH2K7B.js +386 -0
- package/dist/{chunk-BVXGN3AC.js → chunk-TVZWTKJU.js} +316 -224
- package/dist/{chunk-4VHPGJVU.js → chunk-V75HW2AM.js} +8557 -6661
- package/dist/cli.js +23 -9
- package/dist/{installed-IKSARZIK.js → installed-WA6I2IFD.js} +4 -3
- package/dist/{list-IJK225B3.js → list-Y7I5NUWT.js} +3 -2
- package/dist/nextjs-command-4G7N6VPP.js +59 -0
- package/dist/nextjs-installer-5C3VBCZE.js +80 -0
- package/dist/nextjs-setup-YYXNONJ6.js +100 -0
- package/dist/react-command-C47QFAJ5.js +59 -0
- package/dist/{remove-IIT34Y3T.js → remove-JBICRDXX.js} +4 -3
- package/dist/vite-installer-OPE53M3C.js +49 -0
- package/dist/vite-setup-B5TXMX72.js +51 -0
- package/dist/vue-command-6I7JVUI2.js +73 -0
- package/dist/vue-installer-2VSYMM6R.js +74 -0
- package/dist/vue-setup-WY57VJB3.js +91 -0
- package/package.json +5 -2
- package/dist/chunk-QRFLHLFE.js +0 -300
- package/dist/chunk-WKYUK64P.js +0 -308
- package/dist/install-APYIRHSN.js +0 -258
- package/dist/install-nextjs-C3LEKJLY.js +0 -353
package/dist/chunk-WKYUK64P.js
DELETED
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
logger
|
|
3
|
-
} from "./chunk-QRFLHLFE.js";
|
|
4
|
-
|
|
5
|
-
// src/core/validator.ts
|
|
6
|
-
var CompatibilityValidator = class {
|
|
7
|
-
/**
|
|
8
|
-
* @param rules - Règles de compatibilité à appliquer
|
|
9
|
-
*/
|
|
10
|
-
constructor(rules) {
|
|
11
|
-
this.rules = rules;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Valide la compatibilité d'un ensemble de plugins
|
|
15
|
-
*
|
|
16
|
-
* @param plugins - Liste des plugins à valider
|
|
17
|
-
* @param ctx - Contexte du projet (optionnel, pour règles spécifiques framework)
|
|
18
|
-
* @returns Résultat de la validation avec erreurs, warnings et suggestions
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```typescript
|
|
22
|
-
* const result = validator.validate([plugin1, plugin2, plugin3], ctx)
|
|
23
|
-
* if (!result.valid) {
|
|
24
|
-
* // Gérer les erreurs
|
|
25
|
-
* }
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
validate(plugins, ctx) {
|
|
29
|
-
logger.debug(`Validating ${plugins.length} plugin(s)`);
|
|
30
|
-
const pluginNames = new Set(plugins.map((p) => p.name));
|
|
31
|
-
const applicableRules = ctx ? this.rules.filter(
|
|
32
|
-
(rule) => !rule.framework || rule.framework === ctx.framework
|
|
33
|
-
) : this.rules.filter((rule) => !rule.framework);
|
|
34
|
-
const allConflicts = this.checkConflicts(
|
|
35
|
-
plugins,
|
|
36
|
-
pluginNames,
|
|
37
|
-
applicableRules
|
|
38
|
-
);
|
|
39
|
-
const conflictErrors = [];
|
|
40
|
-
const conflictWarnings = [];
|
|
41
|
-
for (const conflict of allConflicts) {
|
|
42
|
-
const rule = applicableRules.find(
|
|
43
|
-
(r) => r.type === "CONFLICT" && r.plugins?.every((p) => conflict.plugins?.includes(p))
|
|
44
|
-
);
|
|
45
|
-
if (rule?.severity === "error") {
|
|
46
|
-
conflictErrors.push(conflict);
|
|
47
|
-
} else {
|
|
48
|
-
conflictWarnings.push(conflict);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
const frameworkConflicts = ctx ? this.checkFrameworkConflicts(plugins, pluginNames, ctx, applicableRules) : [];
|
|
52
|
-
const frameworkErrors = [];
|
|
53
|
-
const frameworkWarnings = [];
|
|
54
|
-
for (const conflict of frameworkConflicts) {
|
|
55
|
-
const rule = applicableRules.find(
|
|
56
|
-
(r) => r.type === "CONFLICT" && r.framework === ctx?.framework && r.plugins?.some((p) => conflict.plugins?.includes(p))
|
|
57
|
-
);
|
|
58
|
-
if (rule?.severity === "error") {
|
|
59
|
-
frameworkErrors.push(conflict);
|
|
60
|
-
} else {
|
|
61
|
-
frameworkWarnings.push(conflict);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
const errors = [
|
|
65
|
-
...this.checkExclusivity(plugins, pluginNames, applicableRules),
|
|
66
|
-
...conflictErrors,
|
|
67
|
-
...this.checkDependencies(plugins, pluginNames, applicableRules),
|
|
68
|
-
...frameworkErrors
|
|
69
|
-
];
|
|
70
|
-
const warnings = [...conflictWarnings, ...frameworkWarnings];
|
|
71
|
-
const suggestions = this.checkRecommendations(
|
|
72
|
-
plugins,
|
|
73
|
-
pluginNames,
|
|
74
|
-
applicableRules
|
|
75
|
-
);
|
|
76
|
-
const valid = errors.length === 0;
|
|
77
|
-
logger.debug(`Validation result: ${valid ? "valid" : "invalid"}`, {
|
|
78
|
-
errors: errors.length,
|
|
79
|
-
warnings: warnings.length,
|
|
80
|
-
suggestions: suggestions.length
|
|
81
|
-
});
|
|
82
|
-
return {
|
|
83
|
-
valid,
|
|
84
|
-
errors,
|
|
85
|
-
warnings,
|
|
86
|
-
suggestions
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Vérifie les conflits avec le framework
|
|
91
|
-
*
|
|
92
|
-
* @param _plugins - Liste des plugins (non utilisée, conservée pour cohérence)
|
|
93
|
-
* @param pluginNames - Set des noms de plugins pour lookup rapide
|
|
94
|
-
* @param ctx - Contexte du projet
|
|
95
|
-
* @param rules - Règles applicables
|
|
96
|
-
* @returns Liste des erreurs/warnings de conflit framework
|
|
97
|
-
*
|
|
98
|
-
* @internal
|
|
99
|
-
*/
|
|
100
|
-
checkFrameworkConflicts(_plugins, pluginNames, ctx, rules) {
|
|
101
|
-
const conflicts = [];
|
|
102
|
-
for (const rule of rules) {
|
|
103
|
-
if (rule.type !== "CONFLICT" || !rule.framework || rule.framework !== ctx.framework) {
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
if (rule.plugins && rule.plugins.length > 0) {
|
|
107
|
-
const conflictingPlugins = rule.plugins.filter(
|
|
108
|
-
(pluginName) => pluginNames.has(pluginName)
|
|
109
|
-
);
|
|
110
|
-
if (conflictingPlugins.length > 0) {
|
|
111
|
-
conflicts.push({
|
|
112
|
-
type: "CONFLICT",
|
|
113
|
-
plugins: conflictingPlugins,
|
|
114
|
-
message: rule.reason,
|
|
115
|
-
canOverride: rule.allowOverride ?? true
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return conflicts;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Vérifie les règles d'exclusivité (EXCLUSIVE)
|
|
124
|
-
*
|
|
125
|
-
* @param _plugins - Liste des plugins (non utilisée, conservée pour cohérence)
|
|
126
|
-
* @param pluginNames - Set des noms de plugins pour lookup rapide
|
|
127
|
-
* @param rules - Règles applicables
|
|
128
|
-
* @returns Liste des erreurs d'exclusivité
|
|
129
|
-
*
|
|
130
|
-
* @internal
|
|
131
|
-
*/
|
|
132
|
-
checkExclusivity(_plugins, pluginNames, rules = this.rules) {
|
|
133
|
-
const errors = [];
|
|
134
|
-
for (const rule of rules) {
|
|
135
|
-
if (rule.type !== "EXCLUSIVE" || !rule.plugins) {
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
const selectedExclusivePlugins = rule.plugins.filter(
|
|
139
|
-
(pluginName) => pluginNames.has(pluginName)
|
|
140
|
-
);
|
|
141
|
-
if (selectedExclusivePlugins.length > 1) {
|
|
142
|
-
errors.push({
|
|
143
|
-
type: "EXCLUSIVE",
|
|
144
|
-
plugins: selectedExclusivePlugins,
|
|
145
|
-
message: rule.reason,
|
|
146
|
-
canOverride: rule.allowOverride ?? false
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return errors;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Vérifie les conflits entre plugins (CONFLICT)
|
|
154
|
-
*
|
|
155
|
-
* @param _plugins - Liste des plugins (non utilisée, conservée pour cohérence)
|
|
156
|
-
* @param pluginNames - Set des noms de plugins pour lookup rapide
|
|
157
|
-
* @param rules - Règles applicables
|
|
158
|
-
* @returns Liste des warnings/erreurs de conflit
|
|
159
|
-
*
|
|
160
|
-
* @internal
|
|
161
|
-
*/
|
|
162
|
-
checkConflicts(_plugins, pluginNames, rules = this.rules) {
|
|
163
|
-
const conflicts = [];
|
|
164
|
-
for (const rule of rules) {
|
|
165
|
-
if (rule.framework) {
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
if (rule.type !== "CONFLICT" || !rule.plugins) {
|
|
169
|
-
continue;
|
|
170
|
-
}
|
|
171
|
-
const conflictingPlugins = rule.plugins.filter(
|
|
172
|
-
(pluginName) => pluginNames.has(pluginName)
|
|
173
|
-
);
|
|
174
|
-
if (conflictingPlugins.length > 1) {
|
|
175
|
-
conflicts.push({
|
|
176
|
-
type: "CONFLICT",
|
|
177
|
-
plugins: conflictingPlugins,
|
|
178
|
-
message: rule.reason,
|
|
179
|
-
canOverride: rule.allowOverride ?? true
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return conflicts;
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Vérifie les dépendances requises (REQUIRES)
|
|
187
|
-
*
|
|
188
|
-
* @param _plugins - Liste des plugins (non utilisée, conservée pour cohérence)
|
|
189
|
-
* @param pluginNames - Set des noms de plugins pour lookup rapide
|
|
190
|
-
* @param rules - Règles applicables
|
|
191
|
-
* @returns Liste des erreurs de dépendances manquantes
|
|
192
|
-
*
|
|
193
|
-
* @internal
|
|
194
|
-
*/
|
|
195
|
-
checkDependencies(_plugins, pluginNames, rules = this.rules) {
|
|
196
|
-
const errors = [];
|
|
197
|
-
for (const rule of rules) {
|
|
198
|
-
if (rule.type !== "REQUIRES" || !rule.plugin || !rule.requires) {
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
if (!pluginNames.has(rule.plugin)) {
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
const missingDependencies = rule.requires.filter(
|
|
205
|
-
(dep) => !pluginNames.has(dep)
|
|
206
|
-
);
|
|
207
|
-
if (missingDependencies.length > 0) {
|
|
208
|
-
errors.push({
|
|
209
|
-
type: "REQUIRES",
|
|
210
|
-
plugin: rule.plugin,
|
|
211
|
-
required: missingDependencies.join(", "),
|
|
212
|
-
message: `${rule.plugin} requires: ${missingDependencies.join(", ")}. ${rule.reason}`,
|
|
213
|
-
canOverride: rule.allowOverride ?? false
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return errors;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Vérifie les recommandations (RECOMMENDS)
|
|
221
|
-
*
|
|
222
|
-
* @param _plugins - Liste des plugins (non utilisée, conservée pour cohérence)
|
|
223
|
-
* @param pluginNames - Set des noms de plugins pour lookup rapide
|
|
224
|
-
* @param rules - Règles applicables
|
|
225
|
-
* @returns Liste des suggestions de plugins recommandés
|
|
226
|
-
*
|
|
227
|
-
* @internal
|
|
228
|
-
*/
|
|
229
|
-
checkRecommendations(_plugins, pluginNames, rules = this.rules) {
|
|
230
|
-
const suggestions = [];
|
|
231
|
-
for (const rule of rules) {
|
|
232
|
-
if (rule.type !== "RECOMMENDS" || !rule.plugin || !rule.recommends) {
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
if (!pluginNames.has(rule.plugin)) {
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
const missingRecommendations = rule.recommends.filter(
|
|
239
|
-
(rec) => !pluginNames.has(rec)
|
|
240
|
-
);
|
|
241
|
-
if (missingRecommendations.length > 0) {
|
|
242
|
-
suggestions.push(
|
|
243
|
-
`${rule.plugin} recommends: ${missingRecommendations.join(", ")}. ${rule.reason}`
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
return suggestions;
|
|
248
|
-
}
|
|
249
|
-
};
|
|
250
|
-
var compatibilityRules = [
|
|
251
|
-
// Exclusivités - State Management
|
|
252
|
-
{
|
|
253
|
-
type: "EXCLUSIVE",
|
|
254
|
-
plugins: ["@reduxjs/toolkit", "zustand", "jotai"],
|
|
255
|
-
reason: "Une seule solution de state management est recommand\xE9e",
|
|
256
|
-
severity: "error",
|
|
257
|
-
allowOverride: false
|
|
258
|
-
},
|
|
259
|
-
// Conflits - CSS Frameworks
|
|
260
|
-
{
|
|
261
|
-
type: "CONFLICT",
|
|
262
|
-
plugins: ["tailwindcss", "bootstrap"],
|
|
263
|
-
reason: "Approches CSS potentiellement conflictuelles",
|
|
264
|
-
severity: "warning",
|
|
265
|
-
allowOverride: true
|
|
266
|
-
},
|
|
267
|
-
// Recommandations - React Router
|
|
268
|
-
{
|
|
269
|
-
type: "RECOMMENDS",
|
|
270
|
-
plugin: "react-router-dom",
|
|
271
|
-
recommends: ["@types/react-router-dom"],
|
|
272
|
-
reason: "Types TypeScript recommand\xE9s pour une meilleure exp\xE9rience de d\xE9veloppement",
|
|
273
|
-
severity: "info"
|
|
274
|
-
},
|
|
275
|
-
// Règles spécifiques Next.js
|
|
276
|
-
// React Router incompatible avec Next.js
|
|
277
|
-
{
|
|
278
|
-
type: "CONFLICT",
|
|
279
|
-
plugins: ["react-router-dom"],
|
|
280
|
-
framework: "nextjs",
|
|
281
|
-
reason: "React Router est incompatible avec Next.js. Next.js a son propre syst\xE8me de routing int\xE9gr\xE9.",
|
|
282
|
-
severity: "error",
|
|
283
|
-
allowOverride: false
|
|
284
|
-
},
|
|
285
|
-
// Framer Motion peut causer des problèmes SSR avec Next.js
|
|
286
|
-
{
|
|
287
|
-
type: "CONFLICT",
|
|
288
|
-
plugins: ["framer-motion"],
|
|
289
|
-
framework: "nextjs",
|
|
290
|
-
reason: "Framer Motion peut causer des probl\xE8mes avec le Server-Side Rendering (SSR) de Next.js. Utilisez des alternatives compatibles SSR ou configurez correctement le dynamic import.",
|
|
291
|
-
severity: "warning",
|
|
292
|
-
allowOverride: true
|
|
293
|
-
},
|
|
294
|
-
// Shadcn/ui nécessite une configuration spéciale pour Next.js
|
|
295
|
-
{
|
|
296
|
-
type: "RECOMMENDS",
|
|
297
|
-
plugin: "shadcn-ui",
|
|
298
|
-
recommends: ["shadcn-ui-nextjs"],
|
|
299
|
-
framework: "nextjs",
|
|
300
|
-
reason: "Pour Next.js, utilisez la variante shadcn-ui-nextjs qui est optimis\xE9e pour React Server Components.",
|
|
301
|
-
severity: "info"
|
|
302
|
-
}
|
|
303
|
-
];
|
|
304
|
-
|
|
305
|
-
export {
|
|
306
|
-
CompatibilityValidator,
|
|
307
|
-
compatibilityRules
|
|
308
|
-
};
|
package/dist/install-APYIRHSN.js
DELETED
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Installer,
|
|
3
|
-
SpinnerManager,
|
|
4
|
-
displayInstallationReport,
|
|
5
|
-
getTranslations,
|
|
6
|
-
promptConfirmation,
|
|
7
|
-
promptLanguage,
|
|
8
|
-
promptPluginSelection
|
|
9
|
-
} from "./chunk-OAAGGK2H.js";
|
|
10
|
-
import {
|
|
11
|
-
CompatibilityValidator,
|
|
12
|
-
compatibilityRules
|
|
13
|
-
} from "./chunk-WKYUK64P.js";
|
|
14
|
-
import {
|
|
15
|
-
BackupManager,
|
|
16
|
-
ConfigWriter,
|
|
17
|
-
pluginRegistry
|
|
18
|
-
} from "./chunk-4VHPGJVU.js";
|
|
19
|
-
import {
|
|
20
|
-
DetectionError,
|
|
21
|
-
detectContext
|
|
22
|
-
} from "./chunk-BVXGN3AC.js";
|
|
23
|
-
import {
|
|
24
|
-
checkPathExists,
|
|
25
|
-
logger
|
|
26
|
-
} from "./chunk-QRFLHLFE.js";
|
|
27
|
-
import "./chunk-QGM4M3NI.js";
|
|
28
|
-
|
|
29
|
-
// src/cli/prompts/vite-setup.ts
|
|
30
|
-
import inquirer from "inquirer";
|
|
31
|
-
async function promptViteSetup(language) {
|
|
32
|
-
const t = getTranslations(language);
|
|
33
|
-
const answers = await inquirer.prompt([
|
|
34
|
-
{
|
|
35
|
-
type: "confirm",
|
|
36
|
-
name: "shouldCreate",
|
|
37
|
-
message: t.vite.proposeSetup,
|
|
38
|
-
default: true
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
type: "input",
|
|
42
|
-
name: "projectName",
|
|
43
|
-
message: t.vite.projectName,
|
|
44
|
-
default: t.vite.projectNamePlaceholder,
|
|
45
|
-
when: (answers2) => answers2.shouldCreate === true,
|
|
46
|
-
validate: (input) => {
|
|
47
|
-
if (!input || input.trim().length === 0) {
|
|
48
|
-
return t.vite.validation.empty;
|
|
49
|
-
}
|
|
50
|
-
if (!/^[a-z0-9-_]+$/i.test(input)) {
|
|
51
|
-
return t.vite.validation.invalid;
|
|
52
|
-
}
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
type: "list",
|
|
58
|
-
name: "template",
|
|
59
|
-
message: t.vite.template,
|
|
60
|
-
choices: t.vite.templateOptions,
|
|
61
|
-
when: (answers2) => answers2.shouldCreate === true
|
|
62
|
-
}
|
|
63
|
-
]);
|
|
64
|
-
if (!answers.shouldCreate) {
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
projectName: answers.projectName.trim(),
|
|
69
|
-
template: answers.template
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// src/cli/utils/vite-installer.ts
|
|
74
|
-
import { resolve } from "path";
|
|
75
|
-
import { execa } from "execa";
|
|
76
|
-
async function createViteProject(options, currentDir, language) {
|
|
77
|
-
const t = getTranslations(language);
|
|
78
|
-
const { projectName, template } = options;
|
|
79
|
-
const projectPath = resolve(currentDir, projectName);
|
|
80
|
-
if (await checkPathExists(projectPath)) {
|
|
81
|
-
throw new Error(t.vite.folderExists(projectName));
|
|
82
|
-
}
|
|
83
|
-
logger.info(t.vite.creating);
|
|
84
|
-
try {
|
|
85
|
-
const result = await execa(
|
|
86
|
-
"npm",
|
|
87
|
-
["create", "vite@latest", projectName, "--", "--template", template],
|
|
88
|
-
{
|
|
89
|
-
cwd: currentDir,
|
|
90
|
-
stdio: "inherit",
|
|
91
|
-
env: {
|
|
92
|
-
...process.env,
|
|
93
|
-
// Désactiver les prompts interactifs de Vite
|
|
94
|
-
npm_config_yes: "true"
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
);
|
|
98
|
-
if (result.exitCode !== 0) {
|
|
99
|
-
throw new Error(`${t.vite.error}: exit code ${result.exitCode}`);
|
|
100
|
-
}
|
|
101
|
-
logger.success(t.vite.success);
|
|
102
|
-
logger.info(t.vite.changingDirectory);
|
|
103
|
-
return projectPath;
|
|
104
|
-
} catch (error) {
|
|
105
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
106
|
-
logger.error(`${t.vite.error}: ${errorMessage}`);
|
|
107
|
-
throw error;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// src/cli/commands/install.ts
|
|
112
|
-
import pc from "picocolors";
|
|
113
|
-
async function installReact(options) {
|
|
114
|
-
try {
|
|
115
|
-
const language = await promptLanguage();
|
|
116
|
-
const t = getTranslations(language);
|
|
117
|
-
console.log();
|
|
118
|
-
console.log(pc.bold(pc.cyan(`\u{1F50D} ${t.detection.detecting}`)));
|
|
119
|
-
let projectRoot = process.cwd();
|
|
120
|
-
let ctx;
|
|
121
|
-
try {
|
|
122
|
-
ctx = await detectContext(projectRoot);
|
|
123
|
-
} catch (error) {
|
|
124
|
-
if (error instanceof DetectionError) {
|
|
125
|
-
console.log();
|
|
126
|
-
console.log(pc.yellow(t.vite.noReactDetected));
|
|
127
|
-
console.log();
|
|
128
|
-
const viteOptions = await promptViteSetup(language);
|
|
129
|
-
if (!viteOptions) {
|
|
130
|
-
console.log();
|
|
131
|
-
console.log(pc.gray(t.common.cancel));
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
const newProjectPath = await createViteProject(
|
|
135
|
-
viteOptions,
|
|
136
|
-
projectRoot,
|
|
137
|
-
language
|
|
138
|
-
);
|
|
139
|
-
process.chdir(newProjectPath);
|
|
140
|
-
projectRoot = newProjectPath;
|
|
141
|
-
console.log();
|
|
142
|
-
ctx = await detectContext(projectRoot);
|
|
143
|
-
} else {
|
|
144
|
-
throw error;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
console.log(
|
|
148
|
-
pc.green(` \u2713 ${t.detection.framework}: `) + pc.bold(`${ctx.framework} ${pc.gray(ctx.frameworkVersion)}`)
|
|
149
|
-
);
|
|
150
|
-
console.log(
|
|
151
|
-
pc.green(` \u2713 ${t.detection.typescript}: `) + pc.bold(ctx.typescript ? "Oui" : "Non")
|
|
152
|
-
);
|
|
153
|
-
if (ctx.bundler) {
|
|
154
|
-
console.log(
|
|
155
|
-
pc.green(` \u2713 ${t.detection.bundler}: `) + pc.bold(`${ctx.bundler} ${pc.gray(ctx.bundlerVersion || "")}`)
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
console.log(
|
|
159
|
-
pc.green(` \u2713 ${t.detection.packageManager}: `) + pc.bold(ctx.packageManager)
|
|
160
|
-
);
|
|
161
|
-
console.log();
|
|
162
|
-
let selectedPlugins = [];
|
|
163
|
-
if (options.yes) {
|
|
164
|
-
logger.info("Using default recommendations (--yes mode)");
|
|
165
|
-
} else {
|
|
166
|
-
selectedPlugins = await promptPluginSelection(
|
|
167
|
-
ctx,
|
|
168
|
-
pluginRegistry,
|
|
169
|
-
language
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
if (selectedPlugins.length === 0) {
|
|
173
|
-
console.log();
|
|
174
|
-
console.log(pc.yellow(`\u26A0\uFE0F ${t.common.selected(0)}`));
|
|
175
|
-
console.log(pc.gray("Exiting..."));
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
console.log();
|
|
179
|
-
console.log(
|
|
180
|
-
pc.bold(pc.green(`\u2713 ${t.common.selected(selectedPlugins.length)}`))
|
|
181
|
-
);
|
|
182
|
-
console.log();
|
|
183
|
-
if (!options.yes && !options.silent) {
|
|
184
|
-
const confirmed = await promptConfirmation(selectedPlugins, language);
|
|
185
|
-
if (!confirmed) {
|
|
186
|
-
console.log(t.common.cancel);
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
if (options.dryRun) {
|
|
191
|
-
console.log();
|
|
192
|
-
console.log(pc.bold(pc.yellow("\u2501".repeat(60))));
|
|
193
|
-
console.log(pc.bold(pc.yellow("\u{1F50D} MODE DRY-RUN (simulation uniquement)")));
|
|
194
|
-
console.log(pc.bold(pc.yellow("\u2501".repeat(60))));
|
|
195
|
-
console.log();
|
|
196
|
-
console.log(pc.bold(pc.cyan("\u{1F4E6} Packages \xE0 installer :")));
|
|
197
|
-
for (const plugin of selectedPlugins) {
|
|
198
|
-
console.log(
|
|
199
|
-
pc.blue(` \u2022 ${plugin.displayName}`) + pc.gray(
|
|
200
|
-
` (${plugin.name}${plugin.version ? `@${plugin.version}` : ""})`
|
|
201
|
-
)
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
console.log();
|
|
205
|
-
console.log(pc.bold(pc.cyan("\u{1F4DD} Fichiers qui seraient cr\xE9\xE9s/modifi\xE9s :")));
|
|
206
|
-
for (const plugin of selectedPlugins) {
|
|
207
|
-
console.log(pc.gray(` \u2022 ${plugin.displayName} configuration`));
|
|
208
|
-
}
|
|
209
|
-
console.log();
|
|
210
|
-
console.log(
|
|
211
|
-
pc.yellow("\u26A0\uFE0F Aucune modification n'a \xE9t\xE9 effectu\xE9e (dry-run)")
|
|
212
|
-
);
|
|
213
|
-
console.log(
|
|
214
|
-
pc.cyan("\u{1F4A1} Ex\xE9cutez sans --dry-run pour appliquer les changements")
|
|
215
|
-
);
|
|
216
|
-
console.log();
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
const backupManager = new BackupManager();
|
|
220
|
-
const configWriter = new ConfigWriter(backupManager);
|
|
221
|
-
const validator = new CompatibilityValidator(compatibilityRules);
|
|
222
|
-
const installer = new Installer(ctx, validator, configWriter, backupManager);
|
|
223
|
-
if (options.install === false) {
|
|
224
|
-
console.log();
|
|
225
|
-
console.log(pc.yellow("\u2699\uFE0F Mode configuration uniquement (--no-install)"));
|
|
226
|
-
console.log(pc.gray("Les packages ne seront PAS install\xE9s"));
|
|
227
|
-
console.log();
|
|
228
|
-
}
|
|
229
|
-
const spinner = new SpinnerManager();
|
|
230
|
-
spinner.start(t.installation.installing);
|
|
231
|
-
try {
|
|
232
|
-
const result = await installer.install(selectedPlugins, {
|
|
233
|
-
skipPackageInstall: options.install === false
|
|
234
|
-
});
|
|
235
|
-
spinner.succeed(t.installation.success);
|
|
236
|
-
if (result.success) {
|
|
237
|
-
displayInstallationReport(result, selectedPlugins, language);
|
|
238
|
-
} else {
|
|
239
|
-
console.error(`
|
|
240
|
-
${t.installation.error}`);
|
|
241
|
-
process.exit(1);
|
|
242
|
-
}
|
|
243
|
-
} catch (error) {
|
|
244
|
-
spinner.fail(t.installation.error);
|
|
245
|
-
throw error;
|
|
246
|
-
}
|
|
247
|
-
} catch (error) {
|
|
248
|
-
logger.error("Installation failed:", error);
|
|
249
|
-
if (error instanceof Error) {
|
|
250
|
-
console.error(`
|
|
251
|
-
\u274C ${error.message}`);
|
|
252
|
-
}
|
|
253
|
-
process.exit(1);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
export {
|
|
257
|
-
installReact
|
|
258
|
-
};
|