@configjs/cli 1.1.4 → 1.1.5

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/dist/cli.js CHANGED
@@ -5,7 +5,7 @@ import "./chunk-QGM4M3NI.js";
5
5
  import { Command } from "commander";
6
6
 
7
7
  // package.json
8
- var version = "1.1.4";
8
+ var version = "1.1.5";
9
9
 
10
10
  // src/cli.ts
11
11
  var program = new Command();
@@ -13,8 +13,9 @@ program.name("confjs").description("Configure your frontend stack, instantly").v
13
13
  program.command("react").description("Configure a React project").option("-y, --yes", "Accept all defaults").option("-d, --dry-run", "Simulate without writing to disk").option("-s, --silent", "Non-interactive mode").option("--debug", "Enable debug logs").option("-c, --config <file>", "Use configuration file").option("-f, --force", "Force installation (overwrite configs)").option("--no-install", "Generate configs only, skip package installation").action(
14
14
  async (options) => {
15
15
  try {
16
- const { installReact } = await import("./install-APYIRHSN.js");
17
- await installReact(options);
16
+ const { ReactCommand } = await import("./react-command-DTIKCCPO.js");
17
+ const command = new ReactCommand();
18
+ await command.execute(options);
18
19
  } catch (error) {
19
20
  console.error("Error:", error);
20
21
  process.exit(1);
@@ -24,8 +25,21 @@ program.command("react").description("Configure a React project").option("-y, --
24
25
  program.command("nextjs").description("Configure a Next.js project").option("-y, --yes", "Accept all defaults").option("-d, --dry-run", "Simulate without writing to disk").option("-s, --silent", "Non-interactive mode").option("--debug", "Enable debug logs").option("-c, --config <file>", "Use configuration file").option("-f, --force", "Force installation (overwrite configs)").option("--no-install", "Generate configs only, skip package installation").action(
25
26
  async (options) => {
26
27
  try {
27
- const { installNextjs } = await import("./install-nextjs-C3LEKJLY.js");
28
- await installNextjs(options);
28
+ const { NextjsCommand } = await import("./nextjs-command-AUVNEBHG.js");
29
+ const command = new NextjsCommand();
30
+ await command.execute(options);
31
+ } catch (error) {
32
+ console.error("Error:", error);
33
+ process.exit(1);
34
+ }
35
+ }
36
+ );
37
+ program.command("vue").description("Configure a Vue.js project").option("-y, --yes", "Accept all defaults").option("-d, --dry-run", "Simulate without writing to disk").option("-s, --silent", "Non-interactive mode").option("--debug", "Enable debug logs").option("-c, --config <file>", "Use configuration file").option("-f, --force", "Force installation (overwrite configs)").option("--no-install", "Generate configs only, skip package installation").action(
38
+ async (options) => {
39
+ try {
40
+ const { VueCommand } = await import("./vue-command-R4XETTRT.js");
41
+ const command = new VueCommand();
42
+ await command.execute(options);
29
43
  } catch (error) {
30
44
  console.error("Error:", error);
31
45
  process.exit(1);
@@ -34,7 +48,7 @@ program.command("nextjs").description("Configure a Next.js project").option("-y,
34
48
  );
35
49
  program.command("list").description("List available libraries").option("-c, --category <category>", "Filter by category").action(async (options) => {
36
50
  try {
37
- const { listLibraries } = await import("./list-IJK225B3.js");
51
+ const { listLibraries } = await import("./list-Y7I5NUWT.js");
38
52
  listLibraries(options);
39
53
  } catch (error) {
40
54
  console.error("Error:", error);
@@ -43,7 +57,7 @@ program.command("list").description("List available libraries").option("-c, --ca
43
57
  });
44
58
  program.command("check").description("Check compatibility without installing").option("-c, --config <file>", "Configuration file to check").action(async (options) => {
45
59
  try {
46
- const { checkCompatibility } = await import("./check-XDGAGYOE.js");
60
+ const { checkCompatibility } = await import("./check-AJCBQBFD.js");
47
61
  await checkCompatibility(options);
48
62
  } catch (error) {
49
63
  console.error("Error:", error);
@@ -52,7 +66,7 @@ program.command("check").description("Check compatibility without installing").o
52
66
  });
53
67
  program.command("installed").description("List installed plugins").action(async () => {
54
68
  try {
55
- const { installedCommand } = await import("./installed-IKSARZIK.js");
69
+ const { installedCommand } = await import("./installed-WA6I2IFD.js");
56
70
  await installedCommand();
57
71
  } catch (error) {
58
72
  console.error("Error:", error);
@@ -61,7 +75,7 @@ program.command("installed").description("List installed plugins").action(async
61
75
  });
62
76
  program.command("remove <plugin>").description("Remove an installed plugin").action(async (plugin) => {
63
77
  try {
64
- const { removeCommand } = await import("./remove-IIT34Y3T.js");
78
+ const { removeCommand } = await import("./remove-JBICRDXX.js");
65
79
  await removeCommand(plugin);
66
80
  } catch (error) {
67
81
  console.error("Error:", error);
@@ -1,17 +1,18 @@
1
1
  import {
2
2
  PluginTracker,
3
3
  detectContext
4
- } from "./chunk-BVXGN3AC.js";
4
+ } from "./chunk-TVZWTKJU.js";
5
+ import "./chunk-MQV3WNMH.js";
5
6
  import {
6
7
  logger
7
- } from "./chunk-QRFLHLFE.js";
8
+ } from "./chunk-HM2JWJOO.js";
8
9
  import "./chunk-QGM4M3NI.js";
9
10
 
10
11
  // src/cli/commands/installed.ts
11
12
  async function installedCommand() {
12
13
  try {
13
14
  const ctx = await detectContext(process.cwd());
14
- const tracker = new PluginTracker(ctx.projectRoot);
15
+ const tracker = new PluginTracker(ctx.projectRoot, ctx.fsAdapter);
15
16
  await tracker.load();
16
17
  const installedPlugins = tracker.getInstalledPlugins();
17
18
  if (installedPlugins.length === 0) {
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  pluginRegistry
3
- } from "./chunk-4VHPGJVU.js";
4
- import "./chunk-QRFLHLFE.js";
3
+ } from "./chunk-V75HW2AM.js";
4
+ import "./chunk-MQV3WNMH.js";
5
+ import "./chunk-HM2JWJOO.js";
5
6
  import "./chunk-QGM4M3NI.js";
6
7
 
7
8
  // src/cli/commands/list.ts
@@ -0,0 +1,59 @@
1
+ import {
2
+ BaseFrameworkCommand,
3
+ getFrameworkMetadata
4
+ } from "./chunk-CNAEKUBH.js";
5
+ import "./chunk-D37FHAGO.js";
6
+ import "./chunk-V75HW2AM.js";
7
+ import {
8
+ DetectionError,
9
+ detectContext
10
+ } from "./chunk-TVZWTKJU.js";
11
+ import "./chunk-MQV3WNMH.js";
12
+ import "./chunk-HM2JWJOO.js";
13
+ import {
14
+ getTranslations
15
+ } from "./chunk-3V72QFFY.js";
16
+ import "./chunk-QGM4M3NI.js";
17
+
18
+ // src/cli/commands/nextjs-command.ts
19
+ import pc from "picocolors";
20
+ var NextjsCommand = class extends BaseFrameworkCommand {
21
+ getFramework() {
22
+ return "nextjs";
23
+ }
24
+ async getOrCreateContext(projectRoot, language) {
25
+ const t = getTranslations(language);
26
+ const metadata = getFrameworkMetadata("nextjs");
27
+ if (!metadata) {
28
+ throw new Error("Next.js framework metadata not found");
29
+ }
30
+ try {
31
+ return await detectContext(projectRoot);
32
+ } catch (error) {
33
+ if (error instanceof DetectionError) {
34
+ console.log();
35
+ console.log(pc.yellow(t.nextjs.noNextjsDetected));
36
+ console.log();
37
+ const setupOptions = await metadata.getSetupPrompt(language);
38
+ if (!setupOptions) {
39
+ console.log();
40
+ console.log(pc.gray(t.common.cancel));
41
+ throw new Error("Project creation cancelled");
42
+ }
43
+ const newProjectPath = await metadata.createProject(
44
+ setupOptions,
45
+ projectRoot,
46
+ language
47
+ );
48
+ process.chdir(newProjectPath);
49
+ projectRoot = newProjectPath;
50
+ console.log();
51
+ return await detectContext(projectRoot);
52
+ }
53
+ throw error;
54
+ }
55
+ }
56
+ };
57
+ export {
58
+ NextjsCommand
59
+ };
@@ -0,0 +1,80 @@
1
+ import {
2
+ checkPathExists,
3
+ logger
4
+ } from "./chunk-HM2JWJOO.js";
5
+ import {
6
+ getTranslations
7
+ } from "./chunk-3V72QFFY.js";
8
+ import "./chunk-QGM4M3NI.js";
9
+
10
+ // src/cli/utils/nextjs-installer.ts
11
+ import { resolve } from "path";
12
+ import { execa } from "execa";
13
+ async function createNextjsProject(options, currentDir, language) {
14
+ const t = getTranslations(language);
15
+ const {
16
+ projectName,
17
+ typescript,
18
+ eslint,
19
+ tailwind,
20
+ srcDir,
21
+ appRouter,
22
+ importAlias
23
+ } = options;
24
+ const projectPath = resolve(currentDir, projectName);
25
+ if (await checkPathExists(projectPath)) {
26
+ throw new Error(t.nextjs.folderExists(projectName));
27
+ }
28
+ logger.info(t.nextjs.creating);
29
+ try {
30
+ const args = ["create", "next-app@latest", projectName];
31
+ if (typescript) {
32
+ args.push("--typescript");
33
+ } else {
34
+ args.push("--javascript");
35
+ }
36
+ if (eslint) {
37
+ args.push("--eslint");
38
+ } else {
39
+ args.push("--no-eslint");
40
+ }
41
+ if (tailwind) {
42
+ args.push("--tailwind");
43
+ } else {
44
+ args.push("--no-tailwind");
45
+ }
46
+ if (srcDir) {
47
+ args.push("--src-dir");
48
+ } else {
49
+ args.push("--no-src-dir");
50
+ }
51
+ if (appRouter) {
52
+ args.push("--app");
53
+ } else {
54
+ args.push("--pages");
55
+ }
56
+ args.push("--import-alias", importAlias);
57
+ const result = await execa("npm", args, {
58
+ cwd: currentDir,
59
+ stdio: "inherit",
60
+ env: {
61
+ ...process.env,
62
+ // Désactiver les prompts interactifs de create-next-app
63
+ npm_config_yes: "true"
64
+ }
65
+ });
66
+ if (result.exitCode !== 0) {
67
+ throw new Error(`${t.nextjs.error}: exit code ${result.exitCode}`);
68
+ }
69
+ logger.success(t.nextjs.success);
70
+ logger.info(t.nextjs.changingDirectory);
71
+ return projectPath;
72
+ } catch (error) {
73
+ const errorMessage = error instanceof Error ? error.message : String(error);
74
+ logger.error(`${t.nextjs.error}: ${errorMessage}`);
75
+ throw error;
76
+ }
77
+ }
78
+ export {
79
+ createNextjsProject
80
+ };
@@ -0,0 +1,100 @@
1
+ import {
2
+ getTranslations
3
+ } from "./chunk-3V72QFFY.js";
4
+ import "./chunk-QGM4M3NI.js";
5
+
6
+ // src/cli/prompts/nextjs-setup.ts
7
+ import inquirer from "inquirer";
8
+ async function promptNextjsSetup(language) {
9
+ const t = getTranslations(language);
10
+ const answers = await inquirer.prompt([
11
+ {
12
+ type: "confirm",
13
+ name: "shouldCreate",
14
+ message: t.nextjs.proposeSetup,
15
+ default: true
16
+ },
17
+ {
18
+ type: "input",
19
+ name: "projectName",
20
+ message: t.nextjs.projectName,
21
+ default: t.nextjs.projectNamePlaceholder,
22
+ when: (answers2) => answers2.shouldCreate === true,
23
+ validate: (input) => {
24
+ if (!input || input.trim().length === 0) {
25
+ return t.nextjs.validation.empty;
26
+ }
27
+ if (!/^[a-z0-9-_]+$/i.test(input)) {
28
+ return t.nextjs.validation.invalid;
29
+ }
30
+ return true;
31
+ }
32
+ },
33
+ {
34
+ type: "confirm",
35
+ name: "typescript",
36
+ message: t.nextjs.typescript,
37
+ default: true,
38
+ when: (answers2) => answers2.shouldCreate === true
39
+ },
40
+ {
41
+ type: "confirm",
42
+ name: "eslint",
43
+ message: t.nextjs.eslint,
44
+ default: true,
45
+ when: (answers2) => answers2.shouldCreate === true
46
+ },
47
+ {
48
+ type: "confirm",
49
+ name: "tailwind",
50
+ message: t.nextjs.tailwind,
51
+ default: true,
52
+ when: (answers2) => answers2.shouldCreate === true
53
+ },
54
+ {
55
+ type: "confirm",
56
+ name: "srcDir",
57
+ message: t.nextjs.srcDir,
58
+ default: false,
59
+ when: (answers2) => answers2.shouldCreate === true
60
+ },
61
+ {
62
+ type: "confirm",
63
+ name: "appRouter",
64
+ message: t.nextjs.appRouter,
65
+ default: true,
66
+ when: (answers2) => answers2.shouldCreate === true
67
+ },
68
+ {
69
+ type: "input",
70
+ name: "importAlias",
71
+ message: t.nextjs.importAlias,
72
+ default: "@/*",
73
+ when: (answers2) => answers2.shouldCreate === true,
74
+ validate: (input) => {
75
+ if (!input || input.trim().length === 0) {
76
+ return "L'alias d'import ne peut pas \xEAtre vide";
77
+ }
78
+ if (!/^[@~]\/\*$/.test(input.trim())) {
79
+ return "L'alias doit \xEAtre au format @/* ou ~/*";
80
+ }
81
+ return true;
82
+ }
83
+ }
84
+ ]);
85
+ if (!answers.shouldCreate) {
86
+ return null;
87
+ }
88
+ return {
89
+ projectName: answers.projectName.trim(),
90
+ typescript: answers.typescript,
91
+ eslint: answers.eslint,
92
+ tailwind: answers.tailwind,
93
+ srcDir: answers.srcDir,
94
+ appRouter: answers.appRouter,
95
+ importAlias: answers.importAlias.trim()
96
+ };
97
+ }
98
+ export {
99
+ promptNextjsSetup
100
+ };
@@ -0,0 +1,59 @@
1
+ import {
2
+ BaseFrameworkCommand,
3
+ getFrameworkMetadata
4
+ } from "./chunk-CNAEKUBH.js";
5
+ import "./chunk-D37FHAGO.js";
6
+ import "./chunk-V75HW2AM.js";
7
+ import {
8
+ DetectionError,
9
+ detectContext
10
+ } from "./chunk-TVZWTKJU.js";
11
+ import "./chunk-MQV3WNMH.js";
12
+ import "./chunk-HM2JWJOO.js";
13
+ import {
14
+ getTranslations
15
+ } from "./chunk-3V72QFFY.js";
16
+ import "./chunk-QGM4M3NI.js";
17
+
18
+ // src/cli/commands/react-command.ts
19
+ import pc from "picocolors";
20
+ var ReactCommand = class extends BaseFrameworkCommand {
21
+ getFramework() {
22
+ return "react";
23
+ }
24
+ async getOrCreateContext(projectRoot, language) {
25
+ const t = getTranslations(language);
26
+ const metadata = getFrameworkMetadata("react");
27
+ if (!metadata) {
28
+ throw new Error("React framework metadata not found");
29
+ }
30
+ try {
31
+ return await detectContext(projectRoot);
32
+ } catch (error) {
33
+ if (error instanceof DetectionError) {
34
+ console.log();
35
+ console.log(pc.yellow(t.vite.noReactDetected));
36
+ console.log();
37
+ const setupOptions = await metadata.getSetupPrompt(language);
38
+ if (!setupOptions) {
39
+ console.log();
40
+ console.log(pc.gray(t.common.cancel));
41
+ throw new Error("Project creation cancelled");
42
+ }
43
+ const newProjectPath = await metadata.createProject(
44
+ setupOptions,
45
+ projectRoot,
46
+ language
47
+ );
48
+ process.chdir(newProjectPath);
49
+ projectRoot = newProjectPath;
50
+ console.log();
51
+ return await detectContext(projectRoot);
52
+ }
53
+ throw error;
54
+ }
55
+ }
56
+ };
57
+ export {
58
+ ReactCommand
59
+ };
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  PluginTracker,
3
3
  detectContext
4
- } from "./chunk-BVXGN3AC.js";
4
+ } from "./chunk-TVZWTKJU.js";
5
+ import "./chunk-MQV3WNMH.js";
5
6
  import {
6
7
  logger
7
- } from "./chunk-QRFLHLFE.js";
8
+ } from "./chunk-HM2JWJOO.js";
8
9
  import {
9
10
  __commonJS,
10
11
  __require,
@@ -1677,7 +1678,7 @@ var dist_default2 = createPrompt((config, done) => {
1677
1678
  async function removeCommand(pluginName) {
1678
1679
  try {
1679
1680
  const ctx = await detectContext(process.cwd());
1680
- const tracker = new PluginTracker(ctx.projectRoot);
1681
+ const tracker = new PluginTracker(ctx.projectRoot, ctx.fsAdapter);
1681
1682
  await tracker.load();
1682
1683
  if (!pluginName) {
1683
1684
  console.log("\n\u274C Please specify a plugin name to remove.\n");
@@ -0,0 +1,49 @@
1
+ import {
2
+ checkPathExists,
3
+ logger
4
+ } from "./chunk-HM2JWJOO.js";
5
+ import {
6
+ getTranslations
7
+ } from "./chunk-3V72QFFY.js";
8
+ import "./chunk-QGM4M3NI.js";
9
+
10
+ // src/cli/utils/vite-installer.ts
11
+ import { resolve } from "path";
12
+ import { execa } from "execa";
13
+ async function createViteProject(options, currentDir, language) {
14
+ const t = getTranslations(language);
15
+ const { projectName, template } = options;
16
+ const projectPath = resolve(currentDir, projectName);
17
+ if (await checkPathExists(projectPath)) {
18
+ throw new Error(t.vite.folderExists(projectName));
19
+ }
20
+ logger.info(t.vite.creating);
21
+ try {
22
+ const result = await execa(
23
+ "npm",
24
+ ["create", "vite@latest", projectName, "--", "--template", template],
25
+ {
26
+ cwd: currentDir,
27
+ stdio: "inherit",
28
+ env: {
29
+ ...process.env,
30
+ // Désactiver les prompts interactifs de Vite
31
+ npm_config_yes: "true"
32
+ }
33
+ }
34
+ );
35
+ if (result.exitCode !== 0) {
36
+ throw new Error(`${t.vite.error}: exit code ${result.exitCode}`);
37
+ }
38
+ logger.success(t.vite.success);
39
+ logger.info(t.vite.changingDirectory);
40
+ return projectPath;
41
+ } catch (error) {
42
+ const errorMessage = error instanceof Error ? error.message : String(error);
43
+ logger.error(`${t.vite.error}: ${errorMessage}`);
44
+ throw error;
45
+ }
46
+ }
47
+ export {
48
+ createViteProject
49
+ };
@@ -0,0 +1,51 @@
1
+ import {
2
+ getTranslations
3
+ } from "./chunk-3V72QFFY.js";
4
+ import "./chunk-QGM4M3NI.js";
5
+
6
+ // src/cli/prompts/vite-setup.ts
7
+ import inquirer from "inquirer";
8
+ async function promptViteSetup(language) {
9
+ const t = getTranslations(language);
10
+ const answers = await inquirer.prompt([
11
+ {
12
+ type: "confirm",
13
+ name: "shouldCreate",
14
+ message: t.vite.proposeSetup,
15
+ default: true
16
+ },
17
+ {
18
+ type: "input",
19
+ name: "projectName",
20
+ message: t.vite.projectName,
21
+ default: t.vite.projectNamePlaceholder,
22
+ when: (answers2) => answers2.shouldCreate === true,
23
+ validate: (input) => {
24
+ if (!input || input.trim().length === 0) {
25
+ return t.vite.validation.empty;
26
+ }
27
+ if (!/^[a-z0-9-_]+$/i.test(input)) {
28
+ return t.vite.validation.invalid;
29
+ }
30
+ return true;
31
+ }
32
+ },
33
+ {
34
+ type: "list",
35
+ name: "template",
36
+ message: t.vite.template,
37
+ choices: t.vite.templateOptions,
38
+ when: (answers2) => answers2.shouldCreate === true
39
+ }
40
+ ]);
41
+ if (!answers.shouldCreate) {
42
+ return null;
43
+ }
44
+ return {
45
+ projectName: answers.projectName.trim(),
46
+ template: answers.template
47
+ };
48
+ }
49
+ export {
50
+ promptViteSetup
51
+ };
@@ -0,0 +1,73 @@
1
+ import {
2
+ BaseFrameworkCommand,
3
+ getFrameworkMetadata
4
+ } from "./chunk-CNAEKUBH.js";
5
+ import "./chunk-D37FHAGO.js";
6
+ import "./chunk-V75HW2AM.js";
7
+ import {
8
+ DetectionError,
9
+ detectContext
10
+ } from "./chunk-TVZWTKJU.js";
11
+ import "./chunk-MQV3WNMH.js";
12
+ import "./chunk-HM2JWJOO.js";
13
+ import {
14
+ getTranslations
15
+ } from "./chunk-3V72QFFY.js";
16
+ import "./chunk-QGM4M3NI.js";
17
+
18
+ // src/cli/commands/vue-command.ts
19
+ import pc from "picocolors";
20
+ var VueCommand = class extends BaseFrameworkCommand {
21
+ getFramework() {
22
+ return "vue";
23
+ }
24
+ async getOrCreateContext(projectRoot, language) {
25
+ const t = getTranslations(language);
26
+ const metadata = getFrameworkMetadata("vue");
27
+ if (!metadata) {
28
+ throw new Error("Vue.js framework metadata not found");
29
+ }
30
+ try {
31
+ return await detectContext(projectRoot);
32
+ } catch (error) {
33
+ if (error instanceof DetectionError) {
34
+ console.log();
35
+ console.log(pc.yellow(t.vue.noVueDetected));
36
+ console.log();
37
+ const setupOptions = await metadata.getSetupPrompt(language);
38
+ if (!setupOptions) {
39
+ console.log();
40
+ console.log(pc.gray(t.common.cancel));
41
+ throw new Error("Project creation cancelled");
42
+ }
43
+ const newProjectPath = await metadata.createProject(
44
+ setupOptions,
45
+ projectRoot,
46
+ language
47
+ );
48
+ process.chdir(newProjectPath);
49
+ projectRoot = newProjectPath;
50
+ console.log();
51
+ return await detectContext(projectRoot);
52
+ }
53
+ throw error;
54
+ }
55
+ }
56
+ displayFrameworkSpecificInfo(ctx, _t) {
57
+ if (ctx.vueVersion) {
58
+ console.log(
59
+ pc.green(` \u2713 Vue Version: `) + pc.bold(`Vue ${ctx.vueVersion}`)
60
+ );
61
+ }
62
+ if (ctx.vueApi) {
63
+ console.log(
64
+ pc.green(` \u2713 Vue API: `) + pc.bold(
65
+ ctx.vueApi === "composition" ? "Composition API" : "Options API"
66
+ )
67
+ );
68
+ }
69
+ }
70
+ };
71
+ export {
72
+ VueCommand
73
+ };
@@ -0,0 +1,74 @@
1
+ import {
2
+ checkPathExists,
3
+ logger
4
+ } from "./chunk-HM2JWJOO.js";
5
+ import {
6
+ getTranslations
7
+ } from "./chunk-3V72QFFY.js";
8
+ import "./chunk-QGM4M3NI.js";
9
+
10
+ // src/cli/utils/vue-installer.ts
11
+ import { resolve } from "path";
12
+ import { execa } from "execa";
13
+ async function createVueProject(options, currentDir, language) {
14
+ const t = getTranslations(language);
15
+ const { projectName, typescript } = options;
16
+ const projectPath = resolve(currentDir, projectName);
17
+ if (await checkPathExists(projectPath)) {
18
+ throw new Error(t.vue.folderExists(projectName));
19
+ }
20
+ logger.info(t.vue.creating);
21
+ try {
22
+ const template = typescript ? "vue-ts" : "vue";
23
+ const args = [
24
+ "create",
25
+ "vite@latest",
26
+ projectName,
27
+ "--",
28
+ "--template",
29
+ template
30
+ ];
31
+ await execa("npm", args, {
32
+ cwd: currentDir,
33
+ stdio: "inherit"
34
+ });
35
+ logger.info(t.vue.success);
36
+ const optionalDeps = [];
37
+ if (options.router) {
38
+ optionalDeps.push("vue-router@4");
39
+ }
40
+ if (options.pinia) {
41
+ optionalDeps.push("pinia");
42
+ }
43
+ if (options.vitest) {
44
+ optionalDeps.push("vitest", "@vue/test-utils", "@vitest/ui");
45
+ }
46
+ if (options.eslint) {
47
+ optionalDeps.push(
48
+ "eslint",
49
+ "eslint-plugin-vue",
50
+ "@vue/eslint-config-prettier"
51
+ );
52
+ }
53
+ if (options.prettier) {
54
+ optionalDeps.push("prettier", "eslint-config-prettier");
55
+ }
56
+ if (optionalDeps.length > 0) {
57
+ logger.info(
58
+ `Installing optional dependencies: ${optionalDeps.join(", ")}`
59
+ );
60
+ await execa("npm", ["install", ...optionalDeps], {
61
+ cwd: projectPath,
62
+ stdio: "inherit"
63
+ });
64
+ }
65
+ return projectPath;
66
+ } catch (error) {
67
+ const errorMessage = error instanceof Error ? error.message : String(error);
68
+ logger.error(`${t.vue.error}: ${errorMessage}`);
69
+ throw new Error(`${t.vue.error}: ${errorMessage}`);
70
+ }
71
+ }
72
+ export {
73
+ createVueProject
74
+ };