initkit 1.1.0 → 1.2.0
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/package.json +2 -5
- package/src/cli.js +77 -34
- package/src/commands/create.js +173 -84
- package/src/prompts/questions.js +95 -39
- package/src/utils/addonInstaller.js +402 -0
- package/src/utils/cliRunner.js +146 -0
- package/src/utils/frameworkBootstrap.js +304 -0
- package/src/utils/templateGenerator.js +191 -171
- package/src/templates/express.js +0 -915
- package/src/templates/fullstack.js +0 -1236
- package/src/templates/nextjs.js +0 -620
- package/src/templates/react.js +0 -586
- package/src/templates/vue.js +0 -545
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "initkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A modern CLI tool for scaffolding production-ready web projects with live npm version fetching, multiple frameworks, and best practices built-in",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -32,14 +32,11 @@
|
|
|
32
32
|
"vue",
|
|
33
33
|
"express",
|
|
34
34
|
"typescript",
|
|
35
|
-
"fullstack",
|
|
36
|
-
"monorepo",
|
|
37
35
|
"vite",
|
|
38
36
|
"tailwind",
|
|
39
37
|
"redux-toolkit",
|
|
40
38
|
"prisma",
|
|
41
|
-
"docker"
|
|
42
|
-
"turborepo"
|
|
39
|
+
"docker"
|
|
43
40
|
],
|
|
44
41
|
"author": "Shirish Shrestha <shirishshrestha07@gmail.com>",
|
|
45
42
|
"license": "MIT",
|
package/src/cli.js
CHANGED
|
@@ -19,15 +19,41 @@ const packageJson = require('../package.json');
|
|
|
19
19
|
function displayBanner() {
|
|
20
20
|
console.log('');
|
|
21
21
|
console.log(chalk.cyan('╔════════════════════════════════════════════════════════════╗'));
|
|
22
|
-
console.log(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
console.log(
|
|
22
|
+
console.log(
|
|
23
|
+
chalk.cyan('║') +
|
|
24
|
+
chalk.cyan.bold(' ') +
|
|
25
|
+
chalk.cyan('║')
|
|
26
|
+
);
|
|
27
|
+
console.log(
|
|
28
|
+
chalk.cyan('║') +
|
|
29
|
+
chalk.cyan.bold(' Welcome to InitKit CLI! ') +
|
|
30
|
+
chalk.cyan('║')
|
|
31
|
+
);
|
|
32
|
+
console.log(
|
|
33
|
+
chalk.cyan('║') +
|
|
34
|
+
chalk.cyan.bold(' ') +
|
|
35
|
+
chalk.cyan('║')
|
|
36
|
+
);
|
|
37
|
+
console.log(
|
|
38
|
+
chalk.cyan('║') +
|
|
39
|
+
chalk.white(' Scaffold modern web projects with best ') +
|
|
40
|
+
chalk.cyan('║')
|
|
41
|
+
);
|
|
42
|
+
console.log(
|
|
43
|
+
chalk.cyan('║') +
|
|
44
|
+
chalk.white(' practices and lightning-fast speed ⚡ ') +
|
|
45
|
+
chalk.cyan('║')
|
|
46
|
+
);
|
|
47
|
+
console.log(
|
|
48
|
+
chalk.cyan('║') +
|
|
49
|
+
chalk.cyan.bold(' ') +
|
|
50
|
+
chalk.cyan('║')
|
|
51
|
+
);
|
|
28
52
|
console.log(chalk.cyan('╚════════════════════════════════════════════════════════════╝'));
|
|
29
53
|
console.log('');
|
|
30
|
-
console.log(
|
|
54
|
+
console.log(
|
|
55
|
+
chalk.gray(` Version ${packageJson.version} | Made with ❤️ by developers\n`)
|
|
56
|
+
);
|
|
31
57
|
}
|
|
32
58
|
|
|
33
59
|
// Set up the CLI program
|
|
@@ -37,7 +63,9 @@ program
|
|
|
37
63
|
.description(packageJson.description)
|
|
38
64
|
.usage('[command] [options]')
|
|
39
65
|
.version(packageJson.version, '-v, --version', 'Output the current version')
|
|
40
|
-
.addHelpText(
|
|
66
|
+
.addHelpText(
|
|
67
|
+
'after',
|
|
68
|
+
`
|
|
41
69
|
Examples:
|
|
42
70
|
$ initkit # Interactive mode with step-by-step prompts
|
|
43
71
|
$ initkit my-app # Create project with interactive prompts
|
|
@@ -50,7 +78,8 @@ Documentation:
|
|
|
50
78
|
GitHub: https://github.com/shirishshrestha/initkit
|
|
51
79
|
|
|
52
80
|
Need help? Report issues at: https://github.com/shirishshrestha/initkit/issues
|
|
53
|
-
`
|
|
81
|
+
`
|
|
82
|
+
);
|
|
54
83
|
|
|
55
84
|
// Main create command
|
|
56
85
|
program
|
|
@@ -62,9 +91,11 @@ program
|
|
|
62
91
|
.option('--js, --javascript', 'Use JavaScript instead of TypeScript')
|
|
63
92
|
.option('--no-git', 'Skip Git repository initialization')
|
|
64
93
|
.option('--no-install', 'Skip automatic dependency installation')
|
|
65
|
-
.option('-p, --package-manager <manager>', 'Package manager (npm, yarn, pnpm)'
|
|
94
|
+
.option('-p, --package-manager <manager>', 'Package manager (npm, yarn, pnpm)')
|
|
66
95
|
.option('--verbose', 'Show detailed output and logs')
|
|
67
|
-
.addHelpText(
|
|
96
|
+
.addHelpText(
|
|
97
|
+
'after',
|
|
98
|
+
`
|
|
68
99
|
Examples:
|
|
69
100
|
$ initkit create my-react-app
|
|
70
101
|
$ initkit create api-server --template express --typescript
|
|
@@ -80,7 +111,8 @@ The create command guides you through an interactive setup with 13 questions:
|
|
|
80
111
|
7. Additional tools (Docker, CI/CD, Testing)
|
|
81
112
|
8. Package manager choice
|
|
82
113
|
9. Git initialization
|
|
83
|
-
`
|
|
114
|
+
`
|
|
115
|
+
)
|
|
84
116
|
.action(async (projectName, options) => {
|
|
85
117
|
try {
|
|
86
118
|
displayBanner();
|
|
@@ -117,12 +149,12 @@ The create command guides you through an interactive setup with 13 questions:
|
|
|
117
149
|
// Use default configuration
|
|
118
150
|
answers = {
|
|
119
151
|
projectName: projectName || 'my-project',
|
|
120
|
-
projectType: '
|
|
152
|
+
projectType: 'frontend',
|
|
121
153
|
frontend: 'react',
|
|
122
|
-
backend: 'express',
|
|
123
154
|
language: options.javascript ? 'javascript' : 'typescript',
|
|
124
155
|
folderStructure: 'feature-based',
|
|
125
156
|
typescriptStrict: 'strict',
|
|
157
|
+
styling: 'tailwind',
|
|
126
158
|
useGit: options.git !== false,
|
|
127
159
|
installDependencies: options.install !== false,
|
|
128
160
|
packageManager: options.packageManager || 'npm',
|
|
@@ -131,17 +163,20 @@ The create command guides you through an interactive setup with 13 questions:
|
|
|
131
163
|
};
|
|
132
164
|
} else {
|
|
133
165
|
// Interactive prompts
|
|
134
|
-
console.log(chalk.cyan(
|
|
166
|
+
console.log(chalk.cyan("Let's set up your project!\n"));
|
|
135
167
|
const questions = getQuestions(projectName);
|
|
136
168
|
answers = await inquirer.prompt(questions);
|
|
137
|
-
|
|
169
|
+
|
|
138
170
|
// Set additional options from CLI flags
|
|
139
171
|
if (options.javascript) {
|
|
140
172
|
answers.language = 'javascript';
|
|
141
173
|
}
|
|
142
174
|
answers.useGit = options.git !== false;
|
|
143
175
|
answers.installDependencies = options.install !== false;
|
|
144
|
-
|
|
176
|
+
// Only override packageManager if explicitly provided via CLI flag
|
|
177
|
+
if (options.packageManager) {
|
|
178
|
+
answers.packageManager = options.packageManager;
|
|
179
|
+
}
|
|
145
180
|
}
|
|
146
181
|
|
|
147
182
|
// Derive projectPath if not set
|
|
@@ -160,7 +195,6 @@ The create command guides you through an interactive setup with 13 questions:
|
|
|
160
195
|
});
|
|
161
196
|
|
|
162
197
|
// Success message is now part of the comprehensive summary in create.js
|
|
163
|
-
|
|
164
198
|
} catch (error) {
|
|
165
199
|
displayError(error, { projectName });
|
|
166
200
|
process.exit(1);
|
|
@@ -175,27 +209,28 @@ program
|
|
|
175
209
|
console.log(chalk.cyan.bold('\n╔════════════════════════════════════════════════╗'));
|
|
176
210
|
console.log(chalk.cyan.bold('║ InitKit CLI Information ║'));
|
|
177
211
|
console.log(chalk.cyan.bold('╚════════════════════════════════════════════════╝\n'));
|
|
178
|
-
|
|
212
|
+
|
|
179
213
|
console.log(chalk.white.bold('Version: ') + chalk.green(packageJson.version));
|
|
180
214
|
console.log(chalk.white.bold('Description: ') + chalk.gray(packageJson.description));
|
|
181
215
|
console.log(chalk.white.bold('Author: ') + chalk.gray(packageJson.author));
|
|
182
216
|
console.log(chalk.white.bold('License: ') + chalk.gray(packageJson.license));
|
|
183
|
-
console.log(
|
|
184
|
-
|
|
217
|
+
console.log(
|
|
218
|
+
chalk.white.bold('Repository: ') + chalk.blue(packageJson.repository?.url || 'N/A')
|
|
219
|
+
);
|
|
220
|
+
|
|
185
221
|
console.log(chalk.yellow.bold('\nSupported Frameworks:'));
|
|
186
222
|
console.log(chalk.gray(' Frontend: ') + 'React, Vue, Next.js, Angular, Svelte, Nuxt');
|
|
187
223
|
console.log(chalk.gray(' Backend: ') + 'Express, NestJS, Fastify, Koa, Hapi');
|
|
188
224
|
console.log(chalk.gray(' Database: ') + 'PostgreSQL, MongoDB, MySQL, SQLite');
|
|
189
|
-
|
|
225
|
+
|
|
190
226
|
console.log(chalk.yellow.bold('\nFeatures:'));
|
|
191
227
|
console.log(chalk.gray(' ✓ Interactive project scaffolding'));
|
|
192
228
|
console.log(chalk.gray(' ✓ TypeScript & JavaScript support'));
|
|
193
|
-
console.log(chalk.gray(' ✓ Full-stack monorepo with Turborepo'));
|
|
194
229
|
console.log(chalk.gray(' ✓ Docker & Docker Compose'));
|
|
195
230
|
console.log(chalk.gray(' ✓ CI/CD with GitHub Actions'));
|
|
196
231
|
console.log(chalk.gray(' ✓ ESLint, Prettier, Husky'));
|
|
197
232
|
console.log(chalk.gray(' ✓ Automatic rollback on errors'));
|
|
198
|
-
|
|
233
|
+
|
|
199
234
|
console.log(chalk.cyan('\n💡 Get started: ') + chalk.white('initkit --help\n'));
|
|
200
235
|
});
|
|
201
236
|
|
|
@@ -207,35 +242,43 @@ program
|
|
|
207
242
|
console.log(chalk.cyan.bold('\n╔════════════════════════════════════════════════╗'));
|
|
208
243
|
console.log(chalk.cyan.bold('║ Available Templates & Tools ║'));
|
|
209
244
|
console.log(chalk.cyan.bold('╚════════════════════════════════════════════════╝\n'));
|
|
210
|
-
|
|
245
|
+
|
|
211
246
|
console.log(chalk.yellow.bold('🎨 Frontend Frameworks:'));
|
|
212
|
-
console.log(
|
|
213
|
-
|
|
247
|
+
console.log(
|
|
248
|
+
chalk.gray(' • React ') + chalk.dim('- Popular library for building UIs')
|
|
249
|
+
);
|
|
250
|
+
console.log(
|
|
251
|
+
chalk.gray(' • Vue.js ') + chalk.dim('- Progressive JavaScript framework')
|
|
252
|
+
);
|
|
214
253
|
console.log(chalk.gray(' • Next.js ') + chalk.dim('- React framework with SSR & SSG'));
|
|
215
|
-
console.log(
|
|
254
|
+
console.log(
|
|
255
|
+
chalk.gray(' • Angular ') + chalk.dim('- Platform for building applications')
|
|
256
|
+
);
|
|
216
257
|
console.log(chalk.gray(' • Svelte ') + chalk.dim('- Compile-time framework'));
|
|
217
258
|
console.log(chalk.gray(' • Nuxt.js ') + chalk.dim('- Vue.js framework with SSR'));
|
|
218
|
-
|
|
259
|
+
|
|
219
260
|
console.log(chalk.yellow.bold('\n⚙️ Backend Frameworks:'));
|
|
220
261
|
console.log(chalk.gray(' • Express.js ') + chalk.dim('- Fast, minimalist web framework'));
|
|
221
262
|
console.log(chalk.gray(' • NestJS ') + chalk.dim('- Progressive Node.js framework'));
|
|
222
263
|
console.log(chalk.gray(' • Fastify ') + chalk.dim('- Fast and low overhead'));
|
|
223
264
|
console.log(chalk.gray(' • Koa ') + chalk.dim('- Next generation web framework'));
|
|
224
|
-
console.log(
|
|
225
|
-
|
|
265
|
+
console.log(
|
|
266
|
+
chalk.gray(' • Hapi ') + chalk.dim('- Rich framework for building applications')
|
|
267
|
+
);
|
|
268
|
+
|
|
226
269
|
console.log(chalk.yellow.bold('\n💾 Databases:'));
|
|
227
270
|
console.log(chalk.gray(' • PostgreSQL ') + chalk.dim('- Advanced relational database'));
|
|
228
271
|
console.log(chalk.gray(' • MongoDB ') + chalk.dim('- NoSQL document database'));
|
|
229
272
|
console.log(chalk.gray(' • MySQL ') + chalk.dim('- Popular relational database'));
|
|
230
273
|
console.log(chalk.gray(' • SQLite ') + chalk.dim('- Lightweight embedded database'));
|
|
231
|
-
|
|
274
|
+
|
|
232
275
|
console.log(chalk.yellow.bold('\n🎨 Styling Solutions:'));
|
|
233
276
|
console.log(chalk.gray(' • Tailwind CSS ') + chalk.dim('- Utility-first CSS framework'));
|
|
234
277
|
console.log(chalk.gray(' • CSS Modules ') + chalk.dim('- Locally scoped CSS'));
|
|
235
278
|
console.log(chalk.gray(' • Styled Comp. ') + chalk.dim('- CSS-in-JS solution'));
|
|
236
279
|
console.log(chalk.gray(' • Sass/SCSS ') + chalk.dim('- CSS preprocessor'));
|
|
237
280
|
console.log(chalk.gray(' • Emotion ') + chalk.dim('- Performant CSS-in-JS'));
|
|
238
|
-
|
|
281
|
+
|
|
239
282
|
console.log(chalk.yellow.bold('\n🛠️ Development Tools:'));
|
|
240
283
|
console.log(chalk.gray(' • Docker ') + chalk.dim('- Containerization'));
|
|
241
284
|
console.log(chalk.gray(' • GitHub Actions ') + chalk.dim('- CI/CD automation'));
|
|
@@ -243,7 +286,7 @@ program
|
|
|
243
286
|
console.log(chalk.gray(' • Prettier ') + chalk.dim('- Code formatting'));
|
|
244
287
|
console.log(chalk.gray(' • Jest/Vitest ') + chalk.dim('- Testing frameworks'));
|
|
245
288
|
console.log(chalk.gray(' • Turborepo ') + chalk.dim('- Monorepo build system'));
|
|
246
|
-
|
|
289
|
+
|
|
247
290
|
console.log(chalk.cyan('\n💡 Create a project: ') + chalk.white('initkit [project-name]\n'));
|
|
248
291
|
});
|
|
249
292
|
|
package/src/commands/create.js
CHANGED
|
@@ -3,42 +3,42 @@ import path from 'path';
|
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import ora from 'ora';
|
|
5
5
|
import { generateTemplate } from '../utils/templateGenerator.js';
|
|
6
|
-
import { installDependencies } from '../utils/packageManager.js';
|
|
7
6
|
import { initGit } from '../utils/git.js';
|
|
7
|
+
import { bootstrapWithOfficialCLI } from '../utils/frameworkBootstrap.js';
|
|
8
|
+
import { installAddons, hasAddons } from '../utils/addonInstaller.js';
|
|
8
9
|
import {
|
|
9
10
|
CLIError,
|
|
10
11
|
ERROR_CODES,
|
|
11
12
|
withErrorHandling,
|
|
12
13
|
rollbackProject,
|
|
13
|
-
safeFileOperation,
|
|
14
14
|
} from '../utils/errorHandler.js';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Create a new project based on user configuration
|
|
18
|
-
*
|
|
18
|
+
*
|
|
19
19
|
* This is the main orchestration function that:
|
|
20
20
|
* 1. Creates the project directory
|
|
21
21
|
* 2. Generates template files
|
|
22
22
|
* 3. Installs dependencies
|
|
23
23
|
* 4. Initializes Git repository
|
|
24
24
|
* 5. Handles errors with automatic rollback
|
|
25
|
-
*
|
|
25
|
+
*
|
|
26
26
|
* @param {Object} answers - User's configuration from interactive prompts
|
|
27
27
|
* @param {string} answers.projectName - Name of the project (used for directory)
|
|
28
|
-
* @param {string} answers.projectType - Type of project ('frontend'|'backend'|'
|
|
28
|
+
* @param {string} answers.projectType - Type of project ('frontend'|'backend'|'library')
|
|
29
29
|
* @param {string} [answers.frontend] - Frontend framework choice
|
|
30
30
|
* @param {string} [answers.backend] - Backend framework choice
|
|
31
31
|
* @param {string} answers.language - Programming language ('typescript'|'javascript')
|
|
32
32
|
* @param {string} answers.packageManager - Package manager ('npm'|'yarn'|'pnpm')
|
|
33
33
|
* @param {boolean} [answers.gitInit] - Whether to initialize Git repository
|
|
34
|
-
*
|
|
34
|
+
*
|
|
35
35
|
* @param {Object} [options={}] - Additional command-line options
|
|
36
36
|
* @param {boolean} [options.verbose=false] - Show detailed output during creation
|
|
37
37
|
* @param {string} [options.projectPath] - Custom path for project (overrides answers.projectName)
|
|
38
|
-
*
|
|
38
|
+
*
|
|
39
39
|
* @returns {Promise<void>}
|
|
40
40
|
* @throws {CLIError} If project creation fails at any step (automatic rollback triggered)
|
|
41
|
-
*
|
|
41
|
+
*
|
|
42
42
|
* @example
|
|
43
43
|
* // Basic usage
|
|
44
44
|
* await createProject({
|
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
* packageManager: 'npm',
|
|
50
50
|
* gitInit: true
|
|
51
51
|
* });
|
|
52
|
-
*
|
|
52
|
+
*
|
|
53
53
|
* @example
|
|
54
54
|
* // With verbose output
|
|
55
55
|
* await createProject(answers, { verbose: true });
|
|
@@ -57,10 +57,18 @@ import {
|
|
|
57
57
|
async function createProject(answers, options = {}) {
|
|
58
58
|
const { verbose = false, projectPath: customProjectPath } = options;
|
|
59
59
|
const projectPath = customProjectPath || path.join(process.cwd(), answers.projectName);
|
|
60
|
-
let spinner;
|
|
60
|
+
let spinner = ora();
|
|
61
61
|
|
|
62
62
|
try {
|
|
63
|
-
//
|
|
63
|
+
// ============================================
|
|
64
|
+
// STEP 1: Bootstrap with Official Framework CLI
|
|
65
|
+
// ============================================
|
|
66
|
+
spinner = ora({
|
|
67
|
+
text: 'Bootstrapping project with official CLI...',
|
|
68
|
+
color: 'cyan',
|
|
69
|
+
}).start();
|
|
70
|
+
|
|
71
|
+
// Check if directory already exists
|
|
64
72
|
if (await fs.pathExists(projectPath)) {
|
|
65
73
|
throw new CLIError(
|
|
66
74
|
`Directory "${answers.projectName}" already exists!`,
|
|
@@ -69,103 +77,180 @@ async function createProject(answers, options = {}) {
|
|
|
69
77
|
);
|
|
70
78
|
}
|
|
71
79
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
80
|
+
await withErrorHandling(() => bootstrapWithOfficialCLI(projectPath, answers), {
|
|
81
|
+
projectPath,
|
|
82
|
+
rollback: true,
|
|
83
|
+
errorCode: ERROR_CODES.CREATION_FAILED,
|
|
84
|
+
context: { step: 'CLI bootstrapping' },
|
|
85
|
+
});
|
|
77
86
|
|
|
78
|
-
|
|
79
|
-
() => fs.ensureDir(projectPath),
|
|
80
|
-
'Creating project directory'
|
|
81
|
-
);
|
|
87
|
+
spinner.succeed(chalk.green('✓ Base project created'));
|
|
82
88
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
// ============================================
|
|
90
|
+
// STEP 2: Install Add-ons with Official CLIs/Commands
|
|
91
|
+
// ============================================
|
|
92
|
+
if (hasAddons(answers)) {
|
|
93
|
+
spinner = ora({
|
|
94
|
+
text: 'Installing selected libraries and add-ons...',
|
|
95
|
+
color: 'cyan',
|
|
96
|
+
}).start();
|
|
87
97
|
|
|
88
|
-
|
|
89
|
-
await withErrorHandling(
|
|
90
|
-
() => generateTemplate(projectPath, answers),
|
|
91
|
-
{
|
|
98
|
+
await withErrorHandling(() => installAddons(projectPath, answers), {
|
|
92
99
|
projectPath,
|
|
93
100
|
rollback: true,
|
|
94
101
|
errorCode: ERROR_CODES.CREATION_FAILED,
|
|
95
|
-
context: { step: '
|
|
96
|
-
}
|
|
97
|
-
|
|
102
|
+
context: { step: 'add-on installation' },
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
spinner.succeed(chalk.green('✓ Add-ons installed'));
|
|
106
|
+
}
|
|
98
107
|
|
|
99
|
-
|
|
108
|
+
// ============================================
|
|
109
|
+
// STEP 3: Enhance with Custom Folder Structure
|
|
110
|
+
// ============================================
|
|
111
|
+
spinner = ora({
|
|
112
|
+
text: 'Creating custom folder structure...',
|
|
113
|
+
color: 'cyan',
|
|
114
|
+
}).start();
|
|
100
115
|
|
|
101
|
-
|
|
116
|
+
await withErrorHandling(() => generateTemplate(projectPath, answers), {
|
|
117
|
+
projectPath,
|
|
118
|
+
rollback: true,
|
|
119
|
+
errorCode: ERROR_CODES.CREATION_FAILED,
|
|
120
|
+
context: { step: 'folder structure enhancement' },
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
spinner.succeed(chalk.green('✓ Folder structure configured'));
|
|
124
|
+
|
|
125
|
+
// ============================================
|
|
126
|
+
// STEP 4: Install Dependencies
|
|
127
|
+
// ============================================
|
|
128
|
+
spinner = ora({
|
|
129
|
+
text: `Installing dependencies with ${answers.packageManager}...`,
|
|
130
|
+
color: 'cyan',
|
|
131
|
+
}).start();
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
const installCmd = getInstallCommand(answers.packageManager);
|
|
135
|
+
const { execCommand } = await import('../utils/cliRunner.js');
|
|
136
|
+
await execCommand(installCmd, { cwd: projectPath });
|
|
137
|
+
spinner.succeed(chalk.green('✓ Dependencies installed'));
|
|
138
|
+
} catch (error) {
|
|
139
|
+
spinner.warn(chalk.yellow('⚠ Dependency installation had issues'));
|
|
140
|
+
console.log(chalk.gray(` You can run '${answers.packageManager} install' manually\\n`));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// ============================================
|
|
144
|
+
// STEP 5: Initialize Git Repository
|
|
145
|
+
// ============================================
|
|
102
146
|
if (answers.useGit) {
|
|
103
|
-
|
|
104
|
-
|
|
147
|
+
spinner = ora({
|
|
148
|
+
text: 'Initializing Git repository...',
|
|
149
|
+
color: 'cyan',
|
|
150
|
+
}).start();
|
|
151
|
+
|
|
105
152
|
try {
|
|
106
153
|
await initGit(projectPath);
|
|
107
|
-
|
|
154
|
+
spinner.succeed(chalk.green('✓ Git initialized'));
|
|
108
155
|
} catch (error) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (verbose) {
|
|
112
|
-
console.log(chalk.gray(` Reason: ${error.message}`));
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
156
|
+
spinner.warn(chalk.yellow('⚠ Git initialization skipped'));
|
|
116
157
|
|
|
117
|
-
// Step 5: Install dependencies
|
|
118
|
-
if (answers.installDependencies !== false) {
|
|
119
|
-
try {
|
|
120
|
-
await installDependencies(projectPath, answers.packageManager, {
|
|
121
|
-
verbose,
|
|
122
|
-
});
|
|
123
|
-
} catch (error) {
|
|
124
|
-
// Don't fail the entire process if install fails
|
|
125
|
-
console.log(chalk.yellow('\nDependency installation failed'));
|
|
126
|
-
console.log(chalk.gray(' You can install them manually later\n'));
|
|
127
|
-
|
|
128
158
|
if (verbose) {
|
|
129
|
-
console.log(chalk.gray(`
|
|
159
|
+
console.log(chalk.gray(` Reason: ${error.message}`));
|
|
130
160
|
}
|
|
131
161
|
}
|
|
132
|
-
} else {
|
|
133
|
-
console.log(chalk.gray('\n Skipping dependency installation (--no-install)'));
|
|
134
162
|
}
|
|
135
163
|
|
|
136
|
-
//
|
|
137
|
-
|
|
138
|
-
|
|
164
|
+
// ============================================
|
|
165
|
+
// SUCCESS!
|
|
166
|
+
// ============================================
|
|
167
|
+
console.log('\n');
|
|
168
|
+
displaySuccessMessage(answers, projectPath);
|
|
139
169
|
} catch (error) {
|
|
140
170
|
// Stop any running spinners
|
|
141
171
|
if (spinner && spinner.isSpinning) {
|
|
142
|
-
spinner.fail(chalk.red('Project creation failed'));
|
|
172
|
+
spinner.fail(chalk.red('✗ Project creation failed'));
|
|
143
173
|
}
|
|
144
174
|
|
|
175
|
+
console.log(chalk.red('\n✗ Error: ' + error.message));
|
|
176
|
+
|
|
177
|
+
// Rollback project directory
|
|
178
|
+
await rollbackProject(projectPath);
|
|
179
|
+
|
|
145
180
|
// If it's already a CLIError, just re-throw it
|
|
146
181
|
if (error instanceof CLIError) {
|
|
147
182
|
throw error;
|
|
148
183
|
}
|
|
149
184
|
|
|
150
185
|
// Wrap unexpected errors
|
|
151
|
-
throw new CLIError(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
);
|
|
186
|
+
throw new CLIError(`Failed to create project: ${error.message}`, ERROR_CODES.CREATION_FAILED, {
|
|
187
|
+
originalError: error.name,
|
|
188
|
+
path: projectPath,
|
|
189
|
+
});
|
|
156
190
|
}
|
|
157
191
|
}
|
|
158
192
|
|
|
159
193
|
/**
|
|
160
|
-
* Display
|
|
194
|
+
* Display success message after project creation
|
|
161
195
|
* @param {Object} answers - Project configuration
|
|
162
196
|
* @param {string} projectPath - Path to the project
|
|
163
|
-
* @param {boolean} verbose - Show detailed information
|
|
164
197
|
*/
|
|
165
|
-
function
|
|
198
|
+
function displaySuccessMessage(answers, projectPath) {
|
|
199
|
+
const projectName = path.basename(projectPath);
|
|
200
|
+
|
|
201
|
+
console.log(chalk.green.bold('🎉 Project created successfully!\n'));
|
|
202
|
+
console.log(chalk.cyan('Next steps:'));
|
|
203
|
+
console.log(chalk.white(` cd ${projectName}`));
|
|
204
|
+
console.log(chalk.white(` ${answers.packageManager} run dev\n`));
|
|
205
|
+
|
|
206
|
+
// Show installed add-ons
|
|
207
|
+
if (hasAddons(answers)) {
|
|
208
|
+
console.log(chalk.cyan('Installed add-ons:'));
|
|
209
|
+
if (answers.stateManagement && answers.stateManagement !== 'none') {
|
|
210
|
+
console.log(chalk.white(` ✓ State management: ${answers.stateManagement}`));
|
|
211
|
+
}
|
|
212
|
+
if (answers.uiLibrary && answers.uiLibrary !== 'none') {
|
|
213
|
+
console.log(chalk.white(` ✓ UI library: ${answers.uiLibrary}`));
|
|
214
|
+
}
|
|
215
|
+
if (answers.orm && answers.orm !== 'none') {
|
|
216
|
+
console.log(chalk.white(` ✓ ORM: ${answers.orm}`));
|
|
217
|
+
}
|
|
218
|
+
if (answers.authentication && answers.authentication !== 'none') {
|
|
219
|
+
console.log(chalk.white(` ✓ Authentication: ${answers.authentication}`));
|
|
220
|
+
}
|
|
221
|
+
if (answers.testing && answers.testing.length > 0) {
|
|
222
|
+
console.log(chalk.white(` ✓ Testing: ${answers.testing.join(', ')}`));
|
|
223
|
+
}
|
|
224
|
+
console.log();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
console.log(chalk.gray('Happy coding! 🚀\n'));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** * Get install command for package manager
|
|
231
|
+
*/
|
|
232
|
+
function getInstallCommand(packageManager) {
|
|
233
|
+
const commands = {
|
|
234
|
+
npm: 'npm install',
|
|
235
|
+
yarn: 'yarn install',
|
|
236
|
+
pnpm: 'pnpm install',
|
|
237
|
+
bun: 'bun install',
|
|
238
|
+
};
|
|
239
|
+
return commands[packageManager] || 'npm install';
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/** * Display comprehensive success summary after project creation (LEGACY - DEPRECATED)
|
|
243
|
+
* This function is kept for backward compatibility but is no longer used
|
|
244
|
+
* @deprecated Use displaySuccessMessage instead
|
|
245
|
+
*/
|
|
246
|
+
function displaySuccessSummary(answers, projectPath, _verbose = false) {
|
|
166
247
|
console.log('');
|
|
167
248
|
console.log(chalk.green('╔════════════════════════════════════════════════════════════╗'));
|
|
168
|
-
console.log(
|
|
249
|
+
console.log(
|
|
250
|
+
chalk.green('║') +
|
|
251
|
+
chalk.green.bold(' ✨ Project Created Successfully! ✨ ') +
|
|
252
|
+
chalk.green('║')
|
|
253
|
+
);
|
|
169
254
|
console.log(chalk.green('╚════════════════════════════════════════════════════════════╝'));
|
|
170
255
|
console.log('');
|
|
171
256
|
|
|
@@ -173,20 +258,18 @@ function displaySuccessSummary(answers, projectPath, verbose = false) {
|
|
|
173
258
|
console.log(chalk.cyan.bold(' 📦 Project Information'));
|
|
174
259
|
console.log(chalk.white(` ${chalk.gray('Name:')} ${chalk.bold(answers.projectName)}`));
|
|
175
260
|
console.log(chalk.white(` ${chalk.gray('Type:')} ${answers.projectType}`));
|
|
176
|
-
console.log(
|
|
177
|
-
|
|
261
|
+
console.log(
|
|
262
|
+
chalk.white(` ${chalk.gray('Language:')} ${answers.language || 'JavaScript'}`)
|
|
263
|
+
);
|
|
264
|
+
|
|
178
265
|
if (answers.frontend) {
|
|
179
266
|
console.log(chalk.white(` ${chalk.gray('Frontend:')} ${answers.frontend}`));
|
|
180
267
|
}
|
|
181
|
-
|
|
268
|
+
|
|
182
269
|
if (answers.backend) {
|
|
183
270
|
console.log(chalk.white(` ${chalk.gray('Backend:')} ${answers.backend}`));
|
|
184
271
|
}
|
|
185
272
|
|
|
186
|
-
if (answers.fullstackType) {
|
|
187
|
-
console.log(chalk.white(` ${chalk.gray('Architecture:')} ${answers.fullstackType}`));
|
|
188
|
-
}
|
|
189
|
-
|
|
190
273
|
if (answers.database && answers.database !== 'none') {
|
|
191
274
|
console.log(chalk.white(` ${chalk.gray('Database:')} ${answers.database}`));
|
|
192
275
|
}
|
|
@@ -200,7 +283,7 @@ function displaySuccessSummary(answers, projectPath, verbose = false) {
|
|
|
200
283
|
// Features section
|
|
201
284
|
if (answers.features && answers.features.length > 0) {
|
|
202
285
|
console.log(chalk.cyan.bold(' ⚙️ Configured Features'));
|
|
203
|
-
answers.features.forEach(feature => {
|
|
286
|
+
answers.features.forEach((feature) => {
|
|
204
287
|
console.log(chalk.white(` ${chalk.green('✓')} ${feature}`));
|
|
205
288
|
});
|
|
206
289
|
console.log('');
|
|
@@ -209,7 +292,7 @@ function displaySuccessSummary(answers, projectPath, verbose = false) {
|
|
|
209
292
|
// Additional libraries
|
|
210
293
|
if (answers.additionalLibraries && answers.additionalLibraries.length > 0) {
|
|
211
294
|
console.log(chalk.cyan.bold(' 📚 Additional Libraries'));
|
|
212
|
-
answers.additionalLibraries.slice(0, 5).forEach(lib => {
|
|
295
|
+
answers.additionalLibraries.slice(0, 5).forEach((lib) => {
|
|
213
296
|
console.log(chalk.white(` ${chalk.green('✓')} ${lib}`));
|
|
214
297
|
});
|
|
215
298
|
if (answers.additionalLibraries.length > 5) {
|
|
@@ -232,19 +315,25 @@ function displaySuccessSummary(answers, projectPath, verbose = false) {
|
|
|
232
315
|
console.log(chalk.white(` ${chalk.yellow('1.')} Navigate to your project:`));
|
|
233
316
|
console.log(chalk.gray(` cd ${answers.projectName}`));
|
|
234
317
|
console.log('');
|
|
235
|
-
|
|
318
|
+
|
|
236
319
|
if (!packagesInstalled) {
|
|
237
320
|
console.log(chalk.white(` ${chalk.yellow('2.')} Install dependencies:`));
|
|
238
321
|
console.log(chalk.gray(` ${answers.packageManager} install`));
|
|
239
322
|
console.log('');
|
|
240
323
|
}
|
|
241
|
-
|
|
324
|
+
|
|
242
325
|
const stepNum = packagesInstalled ? 2 : 3;
|
|
243
326
|
console.log(chalk.white(` ${chalk.yellow(stepNum + '.')} Start development server:`));
|
|
244
|
-
console.log(
|
|
327
|
+
console.log(
|
|
328
|
+
chalk.gray(
|
|
329
|
+
` ${answers.packageManager} ${answers.packageManager === 'npm' ? 'run ' : ''}dev`
|
|
330
|
+
)
|
|
331
|
+
);
|
|
245
332
|
console.log('');
|
|
246
|
-
|
|
247
|
-
console.log(
|
|
333
|
+
|
|
334
|
+
console.log(
|
|
335
|
+
chalk.white(` ${chalk.yellow(stepNum + 1 + '.')} Read the README for more info:`)
|
|
336
|
+
);
|
|
248
337
|
console.log(chalk.gray(` cat README.md`));
|
|
249
338
|
console.log('');
|
|
250
339
|
|