create-backend-templates 1.0.1

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.
Files changed (50) hide show
  1. package/Readme.md +129 -0
  2. package/bin/index.js +17 -0
  3. package/create-backend-cli-1.1.0.tgz +0 -0
  4. package/package.json +36 -0
  5. package/scripts/verify-templates.js +51 -0
  6. package/src/cli.js +166 -0
  7. package/src/config/repoMap.js +12 -0
  8. package/src/update.js +15 -0
  9. package/src/utils/env.js +45 -0
  10. package/src/utils/git.js +61 -0
  11. package/src/utils/installer.js +74 -0
  12. package/src/utils/scaffold.js +163 -0
  13. package/src/utils/templates.js +0 -0
  14. package/templates/express-ts-prisma-mysql/.env.example +2 -0
  15. package/templates/express-ts-prisma-mysql/README.md +21 -0
  16. package/templates/express-ts-prisma-mysql/package.json +47 -0
  17. package/templates/express-ts-prisma-mysql/src/index.ts +32 -0
  18. package/templates/express-ts-prisma-mysql/src/prisma/schema.prisma +16 -0
  19. package/templates/express-ts-prisma-mysql/tsconfig.json +19 -0
  20. package/templates/express-ts-prisma-postgres/.env.example +2 -0
  21. package/templates/express-ts-prisma-postgres/README.md +21 -0
  22. package/templates/express-ts-prisma-postgres/package.json +47 -0
  23. package/templates/express-ts-prisma-postgres/src/index.ts +32 -0
  24. package/templates/express-ts-prisma-postgres/src/prisma/schema.prisma +16 -0
  25. package/templates/express-ts-prisma-postgres/tsconfig.json +19 -0
  26. package/templates/nest-ts-prisma-mysql/.env.example +1 -0
  27. package/templates/nest-ts-prisma-mysql/README.md +21 -0
  28. package/templates/nest-ts-prisma-mysql/nest-cli.json +8 -0
  29. package/templates/nest-ts-prisma-mysql/package.json +71 -0
  30. package/templates/nest-ts-prisma-mysql/src/app.controller.ts +12 -0
  31. package/templates/nest-ts-prisma-mysql/src/app.module.ts +11 -0
  32. package/templates/nest-ts-prisma-mysql/src/app.service.ts +8 -0
  33. package/templates/nest-ts-prisma-mysql/src/main.ts +8 -0
  34. package/templates/nest-ts-prisma-mysql/src/prisma/prisma.module.ts +9 -0
  35. package/templates/nest-ts-prisma-mysql/src/prisma/prisma.service.ts +9 -0
  36. package/templates/nest-ts-prisma-mysql/src/prisma/schema.prisma +14 -0
  37. package/templates/nest-ts-prisma-mysql/tsconfig.json +21 -0
  38. package/templates/nest-ts-prisma-postgres/.env.example +1 -0
  39. package/templates/nest-ts-prisma-postgres/README.md +21 -0
  40. package/templates/nest-ts-prisma-postgres/nest-cli.json +8 -0
  41. package/templates/nest-ts-prisma-postgres/package.json +71 -0
  42. package/templates/nest-ts-prisma-postgres/src/app.controller.ts +12 -0
  43. package/templates/nest-ts-prisma-postgres/src/app.module.ts +11 -0
  44. package/templates/nest-ts-prisma-postgres/src/app.service.ts +8 -0
  45. package/templates/nest-ts-prisma-postgres/src/main.ts +8 -0
  46. package/templates/nest-ts-prisma-postgres/src/prisma/prisma.module.ts +9 -0
  47. package/templates/nest-ts-prisma-postgres/src/prisma/prisma.service.ts +9 -0
  48. package/templates/nest-ts-prisma-postgres/src/prisma/schema.prisma +14 -0
  49. package/templates/nest-ts-prisma-postgres/tsconfig.json +21 -0
  50. package/test.js +34 -0
package/Readme.md ADDED
@@ -0,0 +1,129 @@
1
+ # Backend Project Generator CLI
2
+
3
+ [![npm version](https://img.shields.io/npm/v/create-backend.svg)](https://www.npmjs.com/package/create-backend)
4
+ [![License](https://img.shields.io/npm/l/create-backend.svg)](https://github.com/dee-raj/create-backend/blob/main/LICENSE)
5
+ [![Node.js Version](https://img.shields.io/node/v/create-backend.svg)](https://nodejs.org/)
6
+
7
+ > ⚡ A fast, interactive CLI to scaffold modern backend projects with **Express** or **NestJS**, MongoDB/MySQL/Postgres, Prisma support, and optional features like Auth, Swagger, Docker, and ESLint.
8
+
9
+ ---
10
+
11
+ ## Features
12
+
13
+ - Scaffold backend projects with **Express.js** or **NestJS**
14
+ - Choose **TypeScript** or **JavaScript**
15
+ - Database support:
16
+ - MongoDB (Mongoose)
17
+ - MySQL (Prisma)
18
+ - PostgreSQL (Prisma)
19
+ - Optional extra features:
20
+ - JWT Authentication
21
+ - Swagger API Docs
22
+ - Docker support
23
+ - ESLint + Prettier setup
24
+ - Git initialized with first commit
25
+ - Interactive CLI with colorized UI and progress bars
26
+ - **Offline ready**: Bundled templates for instant scaffolding without git cloning
27
+ - Works on Windows, macOS, and Linux
28
+
29
+ ---
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ npm install -g create-backend
35
+ ````
36
+
37
+ or via **yarn**
38
+
39
+ ```bash
40
+ yarn global add create-backend
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Usage
46
+
47
+ ### List Available Templates
48
+
49
+ ```bash
50
+ create-backend --list
51
+ ```
52
+
53
+ Output:
54
+
55
+ ```
56
+ • Express + TypeScript (Mongo) → express-ts-mongo
57
+ • NestJS + TypeScript (Mongo) → nest-ts-mongo
58
+ • Express + JavaScript (Mongo) → express-js-mongo
59
+ • Express + TS + Prisma (MySQL) → express-ts-prisma-mysql
60
+ • Express + TS + Prisma (Postgres) → express-ts-prisma-postgres
61
+ • Nest + TS + Prisma (MySQL) → nest-ts-prisma-mysql
62
+ • Nest + TS + Prisma (Postgres) → nest-ts-prisma-postgres
63
+ ```
64
+
65
+ ---
66
+
67
+ ### Generate a New Project
68
+
69
+ Run the CLI:
70
+
71
+ ```bash
72
+ create-backend
73
+ ```
74
+
75
+ Follow the prompts to:
76
+
77
+ 1. Select **Framework** (Express / NestJS)
78
+ 2. Choose **Language** (TypeScript / JavaScript)
79
+ 3. Pick **Database** (MongoDB / MySQL / PostgreSQL)
80
+ 4. Enable optional **features** (Auth, Swagger, Docker, ESLint)
81
+ 5. Specify **Project Name**
82
+
83
+ The CLI will:
84
+
85
+ * Clone the selected template
86
+ * Generate `.env` for your database
87
+ * Install dependencies with progress bar
88
+ * Initialize git and create initial commit
89
+ * Optional features scaffolding
90
+
91
+ ---
92
+
93
+ ### Example
94
+
95
+ ```bash
96
+ ? Choose Framework: Express
97
+ ? Language: JavaScript
98
+ ? Database: MongoDB
99
+ ? Add Features: Auth, Swagger, Docker, ESLint
100
+ ? Project Name: my-backend
101
+ ```
102
+
103
+ After completion:
104
+
105
+ ```bash
106
+ cd my-backend
107
+ npm run dev
108
+ # or
109
+ npm start
110
+ code .
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Contributing
116
+
117
+ Contributions are welcome! Please follow these steps:
118
+
119
+ 1. Fork the repository
120
+ 2. Create a feature branch: `git checkout -b feature/my-feature`
121
+ 3. Commit your changes: `git commit -m 'Add my feature'`
122
+ 4. Push to the branch: `git push origin feature/my-feature`
123
+ 5. Open a Pull Request
124
+
125
+ ---
126
+
127
+ ## License
128
+
129
+ MIT © 2025 [Dhurbaraj N Joshi](https://github.com/dee-raj)
package/bin/index.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import { runCLI, listTemplates } from "../src/cli.js";
3
+ import updateProject from "../src/update.js";
4
+
5
+ const args = process.argv.slice(2);
6
+
7
+ if (args.includes("--list")) {
8
+ listTemplates();
9
+ process.exit(0);
10
+ }
11
+
12
+ if (args[0] === "update") {
13
+ updateProject(args[1]);
14
+ process.exit(0);
15
+ }
16
+
17
+ runCLI();
Binary file
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "create-backend-templates",
3
+ "version": "1.0.1",
4
+ "description": "This is node backend creation with multiples templates and features like jwt & etc.",
5
+ "bin": {
6
+ "create-backend": "./bin/index.js"
7
+ },
8
+ "keywords": [
9
+ "backend",
10
+ "templates",
11
+ "nodejs",
12
+ "express",
13
+ "jwt",
14
+ "nest",
15
+ "mongodb",
16
+ "mongoose",
17
+ "prisma",
18
+ "sql"
19
+ ],
20
+ "license": "ISC",
21
+ "author": "Dhurbaraj N Joshi",
22
+ "type": "module",
23
+ "main": "bin/index.js",
24
+ "scripts": {
25
+ "test": "echo \"Error: no test specified\" && exit 1"
26
+ },
27
+ "dependencies": {
28
+ "chalk": "^5.6.2",
29
+ "cli-progress": "^3.12.0",
30
+ "commander": "^14.0.2",
31
+ "execa": "^9.6.1",
32
+ "fs-extra": "^11.3.3",
33
+ "inquirer": "^13.1.0",
34
+ "ora": "^9.0.0"
35
+ }
36
+ }
@@ -0,0 +1,51 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import { fileURLToPath } from 'url';
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ const templatesDir = path.join(__dirname, '../templates');
10
+ const requiredFiles = ['package.json', 'README.md', 'src/prisma/schema.prisma'];
11
+
12
+ const templates = [
13
+ 'express-ts-prisma-mysql',
14
+ 'express-ts-prisma-postgres',
15
+ 'nest-ts-prisma-mysql',
16
+ 'nest-ts-prisma-postgres'
17
+ ];
18
+
19
+ console.log(chalk.blue('Verifying templates...\n'));
20
+
21
+ let hasErrors = false;
22
+
23
+ templates.forEach(template => {
24
+ const templatePath = path.join(templatesDir, template);
25
+
26
+ if (!fs.existsSync(templatePath)) {
27
+ console.log(chalk.red(`✖ Template missing: ${template}`));
28
+ hasErrors = true;
29
+ return;
30
+ }
31
+
32
+ console.log(chalk.cyan(`Checking ${template}...`));
33
+
34
+ requiredFiles.forEach(file => {
35
+ const filePath = path.join(templatePath, file);
36
+ if (!fs.existsSync(filePath)) {
37
+ console.log(chalk.red(` ✖ Missing file: ${file}`));
38
+ hasErrors = true;
39
+ } else {
40
+ console.log(chalk.green(` ✔ ${file} exists`));
41
+ }
42
+ });
43
+ console.log('');
44
+ });
45
+
46
+ if (hasErrors) {
47
+ console.log(chalk.red('Verification failed with errors.'));
48
+ process.exit(1);
49
+ } else {
50
+ console.log(chalk.green('All templates verified successfully!'));
51
+ }
package/src/cli.js ADDED
@@ -0,0 +1,166 @@
1
+ import inquirer from "inquirer";
2
+ import chalk from "chalk";
3
+ import scaffold from "./utils/scaffold.js";
4
+ import { ensureGitInstalled } from "./utils/git.js";
5
+
6
+ const headline = text => console.log(chalk.bold.bgBlue.white(`\n ${text} \n`));
7
+
8
+ const section = text => console.log(chalk.bold.cyan(`\n› ${text}`));
9
+
10
+ const success = text => console.log(chalk.green(`✔ ${text}`));
11
+
12
+ const warn = text => console.log(chalk.yellow(`⚠ ${text}`));
13
+
14
+ const error = text => console.log(chalk.bold.redBright(`\n✖ ${text}\n`));
15
+
16
+ export function listTemplates() {
17
+ headline("Available Templates");
18
+
19
+ const list = [
20
+ ["Express + TypeScript (Mongo)", "express-ts-mongo"],
21
+ ["NestJS + TypeScript (Mongo)", "nest-ts-mongo"],
22
+ ["Express + JavaScript (Mongo)", "express-js-mongo"],
23
+ ["Express + TS + Prisma (MySQL)", "express-ts-prisma-mysql"],
24
+ ["Express + TS + Prisma (Postgres)", "express-ts-prisma-postgres"],
25
+ ["Nest + TS + Prisma (MySQL)", "nest-ts-prisma-mysql"],
26
+ ["Nest + TS + Prisma (Postgres)", "nest-ts-prisma-postgres"],
27
+ ];
28
+
29
+ list.forEach(([label, key]) =>
30
+ console.log(`${chalk.white("•")} ${chalk.green(label)} ${chalk.gray(`→ ${key}`)}`)
31
+ );
32
+
33
+ console.log(chalk.dim("\nUsage: create-backend --list\n"));
34
+ }
35
+
36
+
37
+ const delay = (ms) => new Promise(res => setTimeout(res, ms));
38
+
39
+ async function typeLine(text, speed = 40) {
40
+ for (let char of text) {
41
+ process.stdout.write(char);
42
+ await delay(speed);
43
+ }
44
+ process.stdout.write("\n");
45
+ }
46
+
47
+ const banner = async () => {
48
+ console.log(
49
+ chalk.blueBright("\n╔══════════════════════════════════════╗") +
50
+ chalk.blueBright("\n║") + chalk.white.bold(" BACKEND PROJECT GENERATOR CLI ") + chalk.blueBright("║") +
51
+ chalk.blueBright("\n╚══════════════════════════════════════╝\n")
52
+ );
53
+ const lines = [
54
+ chalk.green("\n[~] Initializing Backend Generator..."),
55
+ chalk.green("[|] Loading Modules..."),
56
+ chalk.green("[/] Ready")
57
+ ];
58
+
59
+
60
+ for (const line of lines) {
61
+ await typeLine(line, 10);
62
+ await delay(300);
63
+ }
64
+ console.log();
65
+ };
66
+
67
+
68
+ export async function runCLI() {
69
+ try {
70
+ await banner();
71
+ await ensureGitInstalled();
72
+ section("Select technologies\n");
73
+
74
+ const answers = await inquirer.prompt([
75
+ {
76
+ type: "rawlist",
77
+ name: "framework",
78
+ message: chalk.bold.white("Choose Framework"),
79
+ choices: [
80
+ { name: chalk.cyan("Express"), value: "express" },
81
+ { name: chalk.magenta("NestJS"), value: "nest" }
82
+ ],
83
+ theme: {
84
+ style: {
85
+ highlight: (text) => chalk.underline(text)
86
+ }
87
+ }
88
+ },
89
+ {
90
+ type: "rawlist",
91
+ name: "language",
92
+ message: chalk.bold.white("Language"),
93
+ choices: [
94
+ { name: chalk.blueBright("TypeScript"), value: "ts" },
95
+ { name: chalk.yellowBright("JavaScript"), value: "js" }
96
+ ],
97
+ theme: {
98
+ style: {
99
+ highlight: (text) => chalk.underline(text)
100
+ }
101
+ }
102
+ },
103
+ {
104
+ type: "rawlist",
105
+ name: "database",
106
+ message: chalk.bold.white("Database"),
107
+ choices: [
108
+ { name: chalk.green("MongoDB"), value: "mongo" },
109
+ { name: chalk.blue("MySQL"), value: "mysql" },
110
+ { name: chalk.blueBright("PostgreSQL"), value: "postgres" }
111
+ ],
112
+ theme: {
113
+ style: {
114
+ highlight: (text) => chalk.underline(text)
115
+ }
116
+ }
117
+ },
118
+ {
119
+ type: "checkbox",
120
+ name: "features",
121
+ message: chalk.bold.white("Add Features"),
122
+ choices: [
123
+ { name: chalk.green("Auth (JWT)"), value: "auth" },
124
+ { name: chalk.cyan("Swagger Docs"), value: "swagger" },
125
+ { name: chalk.yellow("Docker Support"), value: "docker" },
126
+ { name: chalk.magenta("ESLint Rules"), value: "eslint" }
127
+ ],
128
+ theme: {
129
+ style: {
130
+ highlight: (text) => chalk.underline(text)
131
+ }
132
+ }
133
+ },
134
+ {
135
+ type: "input",
136
+ name: "folder",
137
+ message: chalk.bold.white("Project Name"),
138
+ default: "backend-service"
139
+ }
140
+ ]);
141
+
142
+ const { framework, language, database, features, folder } = answers;
143
+
144
+ let key = `${framework}-${language}-${database}`;
145
+ if (database !== "mongo") key = `${framework}-${language}-prisma-${database}`;
146
+
147
+ section("Template Selected");
148
+ console.log(chalk.green(`→ ${key}`));
149
+
150
+ section("Generating Project...");
151
+ await scaffold(key, folder, database, features);
152
+
153
+ success("Project created successfully.");
154
+ console.log(
155
+ chalk.white("\nNext steps") +
156
+ chalk.gray(" (copy & run):") +
157
+ "\n" +
158
+ chalk.green(` cd ${folder}\n npm run dev `) +
159
+ chalk.gray("// or npm start") +
160
+ "\n code .\n"
161
+ );
162
+ } catch (err) {
163
+ error(`Something went wrong: ${err.message}`);
164
+ process.exit(1);
165
+ }
166
+ }
@@ -0,0 +1,12 @@
1
+ export const repoMap = {
2
+ // available at this version
3
+ "express-ts-mongo": "https://github.com/dee-raj/backend-ts.git",
4
+ "nest-ts-mongo": "https://github.com/dee-raj/nest.git",
5
+ "express-js-mongo": "https://github.com/dee-raj/backend.git|devlopment",
6
+
7
+ // not available at this version
8
+ "express-ts-prisma-mysql": "templates/express-ts-prisma-mysql",
9
+ "express-ts-prisma-postgres": "templates/express-ts-prisma-postgres",
10
+ "nest-ts-prisma-mysql": "templates/nest-ts-prisma-mysql",
11
+ "nest-ts-prisma-postgres": "templates/nest-ts-prisma-postgres"
12
+ };
package/src/update.js ADDED
@@ -0,0 +1,15 @@
1
+ import fs from "fs-extra";
2
+ import { execa } from "execa";
3
+ import ora from "ora";
4
+
5
+ export default async function updateProject(folder) {
6
+ const spinner = ora("Updating project...").start();
7
+
8
+ try {
9
+ if (fs.existsSync(`${folder}/.git`)) await execa("git", ["pull"], { cwd: folder });
10
+ await execa("npm", ["install"], { cwd: folder });
11
+ spinner.succeed("✔ Project updated");
12
+ } catch (e) {
13
+ spinner.fail("Update failed");
14
+ }
15
+ }
@@ -0,0 +1,45 @@
1
+ import fs from "fs-extra";
2
+ import chalk from "chalk";
3
+ import readline from "readline";
4
+
5
+ async function ask(question) {
6
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
7
+ return new Promise(resolve => rl.question(question, ans => {
8
+ rl.close();
9
+ resolve(ans.trim().toLowerCase());
10
+ }));
11
+ }
12
+
13
+ export async function generateEnv(db, folder, projectName = "myapp") {
14
+ // DB template map
15
+ const envTemplates = {
16
+ mongo: `MONGODB_URI="mongodb://localhost:27017/${projectName}"\nPORT=5000`,
17
+ mysql: `DATABASE_URL="mysql://root:password@localhost:3306/${projectName}"\nPORT=5000`,
18
+ postgres: `DATABASE_URL="postgresql://user:password@localhost:5432/${projectName}?schema=public"\nPORT=5000`,
19
+ };
20
+
21
+ if (!envTemplates[db]) {
22
+ console.log(chalk.red(`✘ Unknown database type: ${db}`));
23
+ console.log(chalk.yellow("Supported: mongo | mysql | postgres"));
24
+ return;
25
+ }
26
+
27
+ fs.ensureDirSync(folder); // auto-create target folder if missing
28
+ const envPath = `${folder}/.env`;
29
+
30
+ // If .env already exists, confirm overwrite
31
+ if (fs.existsSync(envPath)) {
32
+ const confirm = await ask(chalk.yellow(".env already exists. Overwrite? (y/n): "));
33
+ if (confirm !== "y") return console.log(chalk.red("✘ Cancelled"));
34
+ }
35
+
36
+ fs.writeFileSync(envPath, envTemplates[db]);
37
+
38
+ // styled success output with typing animation
39
+ const message = "✔ .env file generated successfully";
40
+ for (let char of message) {
41
+ process.stdout.write(chalk.green(char));
42
+ await new Promise(res => setTimeout(res, 12));
43
+ }
44
+ console.log("\n");
45
+ };
@@ -0,0 +1,61 @@
1
+ import { execa } from "execa";
2
+ import chalk from "chalk";
3
+ import fs from "fs-extra";
4
+ import path from "path";
5
+
6
+ // small typing output utility
7
+ async function typeLog(text, color = chalk.white, speed = 10) {
8
+ for (let char of text) {
9
+ process.stdout.write(color(char));
10
+ await new Promise(res => setTimeout(res, speed));
11
+ }
12
+ process.stdout.write("\n");
13
+ }
14
+
15
+ export async function ensureGitInstalled() {
16
+ try {
17
+ const gv = await execa("git", ["--version"]);
18
+ console.log(chalk.green("✔ Found git is already installed and its version: ", gv.stdout));
19
+ } catch (err) {
20
+ console.log(chalk.red("\n✘ Git is not installed on this system."));
21
+ console.log(chalk.yellow("Install Git: https://git-scm.com/downloads\n"));
22
+ process.exit(1);
23
+ }
24
+ }
25
+
26
+ export async function initGit(folder) {
27
+ try {
28
+ // check if .git already exists
29
+ if (fs.existsSync(path.join(folder, ".git"))) {
30
+ console.log(chalk.yellow("⚠ Git repository already initialized. Skipping init.\n"));
31
+ return;
32
+ }
33
+
34
+ // initialize repository
35
+ await typeLog("→ Initializing Git repository...", chalk.cyanBright);
36
+
37
+ await execa("git", ["init"], { cwd: folder });
38
+ await execa("git", ["add", "."], { cwd: folder });
39
+ await execa("git", ["commit", "-m", "Initial commit"], { cwd: folder });
40
+
41
+ // generate .gitignore if not exist
42
+ const gitignorePath = path.join(folder, ".gitignore");
43
+ if (!fs.existsSync(gitignorePath)) {
44
+ fs.writeFileSync(gitignorePath, `
45
+ node_modules
46
+ .env
47
+ dist
48
+ build
49
+ coverage
50
+ *.log
51
+ `);
52
+ await typeLog("✔ .gitignore created", chalk.green);
53
+ }
54
+
55
+ await typeLog("✔ Git initialized successfully and first commit created.", chalk.green);
56
+
57
+ } catch (err) {
58
+ console.log(chalk.red("\n✘ Git initialization failed."));
59
+ console.log(chalk.gray(err.message), "\n");
60
+ }
61
+ }
@@ -0,0 +1,74 @@
1
+ import { execa } from "execa";
2
+ import chalk from "chalk";
3
+ import cliProgress from "cli-progress";
4
+ import ora from "ora";
5
+ import inquirer from "inquirer";
6
+
7
+ /* Detect available package manager */
8
+ async function detectPkgManager() {
9
+ const managers = ["pnpm", "yarn", "bun", "npm"];
10
+ for (const m of managers) {
11
+ try { await execa(m, ["-v"]); return m; }
12
+ catch { }
13
+ }
14
+ return "npm";
15
+ }
16
+
17
+ export async function installDependencies(folder) {
18
+ console.log(chalk.cyan("\nInstalling dependencies...\n"));
19
+
20
+ const pkgManager = await detectPkgManager();
21
+ const spinner = ora(`Using ${pkgManager}...`).start();
22
+
23
+ await new Promise(res => setTimeout(res, 800));
24
+ spinner.succeed(chalk.green(`Detected package manager: ${pkgManager}`));
25
+
26
+ const bar = new cliProgress.SingleBar({
27
+ format: chalk.magenta("Progress") + " |" + chalk.cyan("{bar}") + "| {percentage}%"
28
+ }, cliProgress.Presets.shades_classic);
29
+
30
+ bar.start(100, 0);
31
+
32
+ let percent = 0;
33
+ const interval = setInterval(() => {
34
+ percent = Math.min(percent + 2, 95);
35
+ bar.update(percent);
36
+ }, 250);
37
+
38
+ const startTime = Date.now();
39
+
40
+ try {
41
+ const runner = execa(pkgManager, ["install"], { cwd: folder });
42
+
43
+ runner.stdout?.on("data", d => process.stdout.write(chalk.gray(d.toString())));
44
+ runner.stderr?.on("data", d => process.stdout.write(chalk.red(d.toString())));
45
+
46
+ await runner;
47
+
48
+ clearInterval(interval);
49
+ bar.update(100);
50
+ bar.stop();
51
+
52
+ const time = ((Date.now() - startTime) / 1000).toFixed(1);
53
+ console.log(chalk.green(`\n✔ Dependencies installed successfully in ${time}s\n`));
54
+ return true;
55
+
56
+ } catch (err) {
57
+ clearInterval(interval);
58
+ bar.stop();
59
+ console.log(chalk.red("\n✖ Dependency installation failed"));
60
+ console.log(chalk.red("Error:"), err.message);
61
+
62
+ const { retry } = await inquirer.prompt([
63
+ {
64
+ type: "confirm",
65
+ name: "retry",
66
+ message: "Retry installation?",
67
+ default: true
68
+ }
69
+ ]);
70
+
71
+ if (retry) return await installDependencies(folder);
72
+ else return false;
73
+ }
74
+ }