create-bluecopa-react-app 1.0.16 → 1.0.18
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/bin/create-bluecopa-react-app.js +244 -139
- package/package.json +1 -1
- package/templates/latest/Agent.md +93 -32
- package/templates/latest/README.md +17 -0
- package/templates/latest/app/app.css +1 -2
- package/templates/latest/app/components/app-sidebar.tsx +5 -0
- package/templates/latest/app/components/nav-user.tsx +4 -5
- package/templates/latest/app/routes/statements.tsx +493 -0
- package/templates/latest/app/routes.tsx +2 -0
- package/templates/latest/components.json +1 -2
- package/templates/latest/dist/assets/{__federation_expose_App-DK1ZdBX-.js → __federation_expose_App-CcOhEUCE.js} +1 -1
- package/templates/latest/dist/assets/{client-DqBeHjYu.js → client-uh-HfYnI.js} +6673 -5762
- package/templates/latest/dist/assets/{index-B8EMpf6o.js → index-C1IOBHtM.js} +1 -1
- package/templates/latest/dist/assets/remoteEntry.css +49 -2
- package/templates/latest/dist/assets/remoteEntry.js +1 -1
- package/templates/latest/dist/index.html +2 -2
- package/templates/latest/package-lock.json +11 -11
- package/templates/latest/package.json +1 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { Command } from
|
|
4
|
-
import path from
|
|
5
|
-
import fs from
|
|
6
|
-
import chalk from
|
|
7
|
-
import inquirer from
|
|
8
|
-
import ora from
|
|
9
|
-
import { execSync } from
|
|
10
|
-
import validatePackageName from
|
|
11
|
-
import { fileURLToPath } from
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import fs from "fs-extra";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import inquirer from "inquirer";
|
|
8
|
+
import ora from "ora";
|
|
9
|
+
import { execSync } from "child_process";
|
|
10
|
+
import validatePackageName from "validate-npm-package-name";
|
|
11
|
+
import { fileURLToPath } from "url";
|
|
12
12
|
|
|
13
13
|
// ES module equivalent of __dirname
|
|
14
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -17,19 +17,25 @@ const __dirname = path.dirname(__filename);
|
|
|
17
17
|
const program = new Command();
|
|
18
18
|
|
|
19
19
|
program
|
|
20
|
-
.version(
|
|
21
|
-
.name(
|
|
22
|
-
.description(
|
|
23
|
-
.argument(
|
|
24
|
-
.option(
|
|
25
|
-
.option(
|
|
26
|
-
.option(
|
|
27
|
-
.option(
|
|
28
|
-
.option(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
.version("1.0.5")
|
|
21
|
+
.name("create-bluecopa-react-app")
|
|
22
|
+
.description("Create a new Bluecopa React application")
|
|
23
|
+
.argument("[project-name]", "Name of the project")
|
|
24
|
+
.option("-t, --template <template>", "Template to use (latest)", "latest")
|
|
25
|
+
.option("--typescript", "Use TypeScript template", true)
|
|
26
|
+
.option("--no-typescript", "Use JavaScript template")
|
|
27
|
+
.option("--skip-install", "Skip package installation")
|
|
28
|
+
.option(
|
|
29
|
+
"--package-manager <manager>",
|
|
30
|
+
"Package manager to use (npm, yarn, pnpm)",
|
|
31
|
+
"auto"
|
|
32
|
+
)
|
|
33
|
+
.option("--git", "Initialize git repository", true)
|
|
34
|
+
.option("--no-git", "Skip git initialization")
|
|
35
|
+
.option("--yes", "Skip all prompts and use defaults")
|
|
36
|
+
.addHelpText(
|
|
37
|
+
"after",
|
|
38
|
+
`
|
|
33
39
|
Examples:
|
|
34
40
|
$ create-bluecopa-react-app my-dashboard
|
|
35
41
|
$ create-bluecopa-react-app my-app --template latest
|
|
@@ -43,12 +49,13 @@ Templates:
|
|
|
43
49
|
|
|
44
50
|
For more information, visit:
|
|
45
51
|
https://github.com/bluecopa/blui/tree/dev/packages/boilerplate/react
|
|
46
|
-
`
|
|
52
|
+
`
|
|
53
|
+
)
|
|
47
54
|
.action(async (projectName, options) => {
|
|
48
55
|
try {
|
|
49
56
|
await createApp(projectName, options);
|
|
50
57
|
} catch (error) {
|
|
51
|
-
console.error(chalk.red(
|
|
58
|
+
console.error(chalk.red("Error creating app:"), error.message);
|
|
52
59
|
process.exit(1);
|
|
53
60
|
}
|
|
54
61
|
});
|
|
@@ -66,71 +73,101 @@ async function createApp(projectName, options) {
|
|
|
66
73
|
// 1. Project Name prompt
|
|
67
74
|
if (!appName) {
|
|
68
75
|
// Generate a random default project name
|
|
69
|
-
const adjectives = [
|
|
70
|
-
|
|
71
|
-
|
|
76
|
+
const adjectives = [
|
|
77
|
+
"awesome",
|
|
78
|
+
"stellar",
|
|
79
|
+
"brilliant",
|
|
80
|
+
"dynamic",
|
|
81
|
+
"epic",
|
|
82
|
+
"fantastic",
|
|
83
|
+
"incredible",
|
|
84
|
+
"magnificent",
|
|
85
|
+
"outstanding",
|
|
86
|
+
"spectacular",
|
|
87
|
+
];
|
|
88
|
+
const nouns = [
|
|
89
|
+
"app",
|
|
90
|
+
"dashboard",
|
|
91
|
+
"project",
|
|
92
|
+
"platform",
|
|
93
|
+
"tool",
|
|
94
|
+
"system",
|
|
95
|
+
"solution",
|
|
96
|
+
"interface",
|
|
97
|
+
"portal",
|
|
98
|
+
"workspace",
|
|
99
|
+
];
|
|
100
|
+
const randomAdjective =
|
|
101
|
+
adjectives[Math.floor(Math.random() * adjectives.length)];
|
|
72
102
|
const randomNoun = nouns[Math.floor(Math.random() * nouns.length)];
|
|
73
103
|
const defaultProjectName = `my-${randomAdjective}-${randomNoun}`;
|
|
74
104
|
|
|
75
105
|
prompts.push({
|
|
76
|
-
type:
|
|
77
|
-
name:
|
|
78
|
-
message:
|
|
106
|
+
type: "input",
|
|
107
|
+
name: "projectName",
|
|
108
|
+
message: "What is your project name?",
|
|
79
109
|
default: defaultProjectName,
|
|
80
110
|
validate: (input) => {
|
|
81
|
-
if (!input) return
|
|
111
|
+
if (!input) return "Project name is required";
|
|
82
112
|
const validation = validatePackageName(input);
|
|
83
113
|
if (!validation.validForNewPackages) {
|
|
84
|
-
return
|
|
114
|
+
return (
|
|
115
|
+
validation.errors?.[0] ||
|
|
116
|
+
validation.warnings?.[0] ||
|
|
117
|
+
"Invalid package name"
|
|
118
|
+
);
|
|
85
119
|
}
|
|
86
120
|
return true;
|
|
87
|
-
}
|
|
121
|
+
},
|
|
88
122
|
});
|
|
89
123
|
}
|
|
90
124
|
|
|
91
125
|
// 2. Template selection prompt
|
|
92
126
|
prompts.push({
|
|
93
|
-
type:
|
|
94
|
-
name:
|
|
95
|
-
message:
|
|
127
|
+
type: "list",
|
|
128
|
+
name: "template",
|
|
129
|
+
message: "Select a template:",
|
|
96
130
|
choices: [
|
|
97
|
-
{
|
|
131
|
+
{
|
|
132
|
+
name: "Latest - Basic React Router setup with essential components",
|
|
133
|
+
value: "latest",
|
|
134
|
+
},
|
|
98
135
|
],
|
|
99
|
-
default: selectedTemplate
|
|
136
|
+
default: selectedTemplate,
|
|
100
137
|
});
|
|
101
138
|
|
|
102
139
|
// 3. Git initialization prompt
|
|
103
140
|
prompts.push({
|
|
104
|
-
type:
|
|
105
|
-
name:
|
|
106
|
-
message:
|
|
107
|
-
default: initGit !== false
|
|
141
|
+
type: "confirm",
|
|
142
|
+
name: "initGit",
|
|
143
|
+
message: "Initialize git repository?",
|
|
144
|
+
default: initGit !== false,
|
|
108
145
|
});
|
|
109
146
|
|
|
110
147
|
// 4. Package manager prompt
|
|
111
148
|
prompts.push({
|
|
112
|
-
type:
|
|
113
|
-
name:
|
|
114
|
-
message:
|
|
149
|
+
type: "list",
|
|
150
|
+
name: "packageManager",
|
|
151
|
+
message: "Select package manager:",
|
|
115
152
|
choices: [
|
|
116
|
-
{ name:
|
|
117
|
-
{ name:
|
|
118
|
-
{ name:
|
|
153
|
+
{ name: "pnpm (recommended)", value: "pnpm" },
|
|
154
|
+
{ name: "npm", value: "npm" },
|
|
155
|
+
{ name: "Auto-detect", value: "auto" },
|
|
119
156
|
],
|
|
120
|
-
default: packageManager ===
|
|
157
|
+
default: packageManager === "auto" ? "auto" : packageManager,
|
|
121
158
|
});
|
|
122
159
|
|
|
123
160
|
// 5. Install dependencies prompt
|
|
124
161
|
prompts.push({
|
|
125
|
-
type:
|
|
126
|
-
name:
|
|
127
|
-
message:
|
|
128
|
-
default: !options.skipInstall
|
|
162
|
+
type: "confirm",
|
|
163
|
+
name: "runInstall",
|
|
164
|
+
message: "Do you want to install dependencies now?",
|
|
165
|
+
default: !options.skipInstall,
|
|
129
166
|
});
|
|
130
167
|
|
|
131
168
|
// Execute all prompts
|
|
132
169
|
const answers = await inquirer.prompt(prompts);
|
|
133
|
-
|
|
170
|
+
|
|
134
171
|
// Update values from prompts
|
|
135
172
|
if (answers.projectName) appName = answers.projectName;
|
|
136
173
|
selectedTemplate = answers.template;
|
|
@@ -140,24 +177,35 @@ async function createApp(projectName, options) {
|
|
|
140
177
|
} else {
|
|
141
178
|
// When using --yes flag, validate required options
|
|
142
179
|
if (!appName) {
|
|
143
|
-
console.error(
|
|
180
|
+
console.error(
|
|
181
|
+
chalk.red("Project name is required when using --yes flag")
|
|
182
|
+
);
|
|
144
183
|
process.exit(1);
|
|
145
184
|
}
|
|
146
185
|
}
|
|
147
186
|
|
|
148
187
|
// Validate template
|
|
149
|
-
const validTemplates = [
|
|
188
|
+
const validTemplates = ["latest"];
|
|
150
189
|
if (!validTemplates.includes(selectedTemplate)) {
|
|
151
190
|
console.error(chalk.red(`Invalid template: ${selectedTemplate}`));
|
|
152
|
-
console.error(
|
|
191
|
+
console.error(
|
|
192
|
+
chalk.yellow(`Available templates: ${validTemplates.join(", ")}`)
|
|
193
|
+
);
|
|
153
194
|
process.exit(1);
|
|
154
195
|
}
|
|
155
196
|
|
|
156
197
|
// Validate project name
|
|
157
198
|
const validation = validatePackageName(appName);
|
|
158
199
|
if (!validation.validForNewPackages) {
|
|
159
|
-
console.error(
|
|
160
|
-
|
|
200
|
+
console.error(
|
|
201
|
+
chalk.red("Invalid project name:"),
|
|
202
|
+
validation.errors?.[0] || validation.warnings?.[0]
|
|
203
|
+
);
|
|
204
|
+
console.error(
|
|
205
|
+
chalk.yellow(
|
|
206
|
+
"Project names must be lowercase, contain no spaces, and follow npm naming conventions."
|
|
207
|
+
)
|
|
208
|
+
);
|
|
161
209
|
process.exit(1);
|
|
162
210
|
}
|
|
163
211
|
|
|
@@ -166,20 +214,22 @@ async function createApp(projectName, options) {
|
|
|
166
214
|
// Check if directory already exists
|
|
167
215
|
if (fs.existsSync(targetDir)) {
|
|
168
216
|
if (options.yes) {
|
|
169
|
-
console.log(
|
|
217
|
+
console.log(
|
|
218
|
+
chalk.yellow(`Directory ${appName} already exists. Overwriting...`)
|
|
219
|
+
);
|
|
170
220
|
await fs.remove(targetDir);
|
|
171
221
|
} else {
|
|
172
222
|
const answers = await inquirer.prompt([
|
|
173
223
|
{
|
|
174
|
-
type:
|
|
175
|
-
name:
|
|
224
|
+
type: "confirm",
|
|
225
|
+
name: "overwrite",
|
|
176
226
|
message: `Directory ${appName} already exists. Overwrite?`,
|
|
177
|
-
default: false
|
|
178
|
-
}
|
|
227
|
+
default: false,
|
|
228
|
+
},
|
|
179
229
|
]);
|
|
180
230
|
|
|
181
231
|
if (!answers.overwrite) {
|
|
182
|
-
console.log(chalk.yellow(
|
|
232
|
+
console.log(chalk.yellow("Operation cancelled."));
|
|
183
233
|
return;
|
|
184
234
|
}
|
|
185
235
|
|
|
@@ -187,88 +237,113 @@ async function createApp(projectName, options) {
|
|
|
187
237
|
}
|
|
188
238
|
}
|
|
189
239
|
|
|
190
|
-
console.log(
|
|
240
|
+
console.log(
|
|
241
|
+
chalk.blue(`Creating a new Bluecopa React app in ${chalk.green(targetDir)}`)
|
|
242
|
+
);
|
|
191
243
|
console.log(chalk.gray(`Template: ${selectedTemplate}`));
|
|
192
244
|
console.log();
|
|
193
245
|
|
|
194
246
|
// Create app
|
|
195
|
-
const spinner = ora(
|
|
196
|
-
|
|
247
|
+
const spinner = ora("Creating project structure...").start();
|
|
248
|
+
|
|
197
249
|
try {
|
|
198
|
-
await createProjectStructure(targetDir, appName, {
|
|
199
|
-
|
|
250
|
+
await createProjectStructure(targetDir, appName, {
|
|
251
|
+
...options,
|
|
252
|
+
template: selectedTemplate,
|
|
253
|
+
});
|
|
254
|
+
spinner.succeed("Project structure created");
|
|
200
255
|
|
|
201
256
|
if (!options.skipInstall) {
|
|
202
257
|
const detectedPackageManager = await detectPackageManager(packageManager);
|
|
203
|
-
spinner.start(
|
|
258
|
+
spinner.start(
|
|
259
|
+
`Installing dependencies with ${detectedPackageManager}...`
|
|
260
|
+
);
|
|
204
261
|
await installDependencies(targetDir, detectedPackageManager);
|
|
205
|
-
spinner.succeed(
|
|
262
|
+
spinner.succeed("Dependencies installed");
|
|
206
263
|
} else {
|
|
207
|
-
console.log(
|
|
264
|
+
console.log(
|
|
265
|
+
chalk.yellow(
|
|
266
|
+
"Skipping dependency installation. You can run it manually later."
|
|
267
|
+
)
|
|
268
|
+
);
|
|
208
269
|
}
|
|
209
270
|
|
|
210
271
|
// Post-installation setup
|
|
211
272
|
if (initGit !== false) {
|
|
212
|
-
spinner.start(
|
|
273
|
+
spinner.start("Initializing git repository...");
|
|
213
274
|
await initializeGit(targetDir, appName);
|
|
214
|
-
spinner.succeed(
|
|
275
|
+
spinner.succeed("Git repository initialized");
|
|
215
276
|
}
|
|
216
277
|
|
|
217
|
-
spinner.succeed(
|
|
218
|
-
|
|
278
|
+
spinner.succeed(
|
|
279
|
+
chalk.green("Success! Created " + appName + " at " + targetDir)
|
|
280
|
+
);
|
|
281
|
+
|
|
219
282
|
console.log();
|
|
220
|
-
console.log(
|
|
283
|
+
console.log("Inside that directory, you can run several commands:");
|
|
221
284
|
console.log();
|
|
222
|
-
|
|
285
|
+
|
|
223
286
|
// Show install command if dependencies weren't installed
|
|
224
287
|
if (options.skipInstall) {
|
|
225
288
|
const detectedPackageManager = await detectPackageManager(packageManager);
|
|
226
|
-
const installCommand =
|
|
227
|
-
|
|
228
|
-
|
|
289
|
+
const installCommand =
|
|
290
|
+
detectedPackageManager === "yarn"
|
|
291
|
+
? "yarn install"
|
|
292
|
+
: detectedPackageManager === "pnpm"
|
|
293
|
+
? "pnpm install"
|
|
294
|
+
: "npm install";
|
|
229
295
|
console.log(chalk.cyan(` ${installCommand}`));
|
|
230
|
-
console.log(
|
|
296
|
+
console.log(" Install dependencies first.");
|
|
231
297
|
console.log();
|
|
232
298
|
}
|
|
233
|
-
|
|
234
|
-
const runCommand =
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
299
|
+
|
|
300
|
+
const runCommand =
|
|
301
|
+
packageManager === "pnpm"
|
|
302
|
+
? "pnpm run"
|
|
303
|
+
: packageManager === "yarn"
|
|
304
|
+
? "yarn"
|
|
305
|
+
: "npm run";
|
|
306
|
+
|
|
238
307
|
console.log(chalk.cyan(` ${runCommand} dev`));
|
|
239
|
-
console.log(
|
|
308
|
+
console.log(" Starts the development server.");
|
|
240
309
|
console.log();
|
|
241
310
|
console.log(chalk.cyan(` ${runCommand} build`));
|
|
242
|
-
console.log(
|
|
311
|
+
console.log(" Bundles the app into static files for production.");
|
|
243
312
|
console.log();
|
|
244
313
|
console.log(chalk.cyan(` ${runCommand} start`));
|
|
245
|
-
console.log(
|
|
314
|
+
console.log(" Start the production build locally.");
|
|
246
315
|
console.log();
|
|
247
316
|
console.log(chalk.cyan(` ${runCommand} preview`));
|
|
248
|
-
console.log(
|
|
317
|
+
console.log(" Preview the production build locally.");
|
|
249
318
|
console.log();
|
|
250
|
-
console.log(
|
|
319
|
+
console.log("We suggest that you begin by typing:");
|
|
251
320
|
console.log();
|
|
252
|
-
console.log(chalk.cyan(
|
|
321
|
+
console.log(chalk.cyan(" cd"), appName);
|
|
253
322
|
if (options.skipInstall) {
|
|
254
323
|
const detectedPackageManager = await detectPackageManager(packageManager);
|
|
255
|
-
const installCommand =
|
|
256
|
-
|
|
257
|
-
|
|
324
|
+
const installCommand =
|
|
325
|
+
detectedPackageManager === "yarn"
|
|
326
|
+
? "yarn install"
|
|
327
|
+
: detectedPackageManager === "pnpm"
|
|
328
|
+
? "pnpm install"
|
|
329
|
+
: "npm install";
|
|
258
330
|
console.log(chalk.cyan(` ${installCommand}`));
|
|
259
331
|
}
|
|
260
332
|
console.log(chalk.cyan(` ${runCommand} dev`));
|
|
261
333
|
console.log();
|
|
262
|
-
console.log(
|
|
334
|
+
console.log("Happy coding! 🚀");
|
|
263
335
|
console.log();
|
|
264
|
-
console.log(chalk.gray(
|
|
265
|
-
console.log(
|
|
266
|
-
|
|
336
|
+
console.log(chalk.gray("Need help? Check out the documentation:"));
|
|
337
|
+
console.log(
|
|
338
|
+
chalk.gray(
|
|
339
|
+
" https://github.com/bluecopa/blui/tree/main/packages/boilerplate/react"
|
|
340
|
+
)
|
|
341
|
+
);
|
|
267
342
|
} catch (error) {
|
|
268
|
-
spinner.fail(
|
|
343
|
+
spinner.fail("Failed to create project");
|
|
269
344
|
// Cleanup on failure
|
|
270
345
|
if (fs.existsSync(targetDir)) {
|
|
271
|
-
console.log(chalk.yellow(
|
|
346
|
+
console.log(chalk.yellow("Cleaning up..."));
|
|
272
347
|
await fs.remove(targetDir);
|
|
273
348
|
}
|
|
274
349
|
throw error;
|
|
@@ -276,101 +351,131 @@ async function createApp(projectName, options) {
|
|
|
276
351
|
}
|
|
277
352
|
|
|
278
353
|
async function createProjectStructure(targetDir, appName, options) {
|
|
279
|
-
const templateDir = path.join(__dirname,
|
|
280
|
-
|
|
354
|
+
const templateDir = path.join(__dirname, "../templates", options.template);
|
|
355
|
+
|
|
281
356
|
// Validate template directory exists
|
|
282
|
-
if (!await fs.pathExists(templateDir)) {
|
|
283
|
-
throw new Error(
|
|
357
|
+
if (!(await fs.pathExists(templateDir))) {
|
|
358
|
+
throw new Error(
|
|
359
|
+
`Template '${options.template}' not found at ${templateDir}`
|
|
360
|
+
);
|
|
284
361
|
}
|
|
285
|
-
|
|
362
|
+
|
|
286
363
|
// Create base directory
|
|
287
364
|
await fs.ensureDir(targetDir);
|
|
288
|
-
|
|
365
|
+
|
|
289
366
|
// Copy template files
|
|
290
367
|
await fs.copy(templateDir, targetDir);
|
|
291
|
-
|
|
368
|
+
|
|
292
369
|
// Update package.json with project name
|
|
293
|
-
const packageJsonPath = path.join(targetDir,
|
|
370
|
+
const packageJsonPath = path.join(targetDir, "package.json");
|
|
294
371
|
if (await fs.pathExists(packageJsonPath)) {
|
|
295
372
|
const packageJson = await fs.readJson(packageJsonPath);
|
|
296
373
|
packageJson.name = appName;
|
|
297
374
|
await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
|
|
298
375
|
}
|
|
299
|
-
|
|
376
|
+
|
|
300
377
|
// Update index.html title if it exists
|
|
301
|
-
const indexHtmlPath = path.join(targetDir,
|
|
378
|
+
const indexHtmlPath = path.join(targetDir, "public/index.html");
|
|
302
379
|
if (await fs.pathExists(indexHtmlPath)) {
|
|
303
|
-
let indexHtml = await fs.readFile(indexHtmlPath,
|
|
380
|
+
let indexHtml = await fs.readFile(indexHtmlPath, "utf8");
|
|
304
381
|
indexHtml = indexHtml.replace(/{{APP_NAME}}/g, appName);
|
|
305
382
|
await fs.writeFile(indexHtmlPath, indexHtml);
|
|
306
383
|
}
|
|
307
384
|
|
|
308
385
|
// Update root index.html if it exists
|
|
309
|
-
const rootIndexHtmlPath = path.join(targetDir,
|
|
386
|
+
const rootIndexHtmlPath = path.join(targetDir, "index.html");
|
|
310
387
|
if (await fs.pathExists(rootIndexHtmlPath)) {
|
|
311
|
-
let indexHtml = await fs.readFile(rootIndexHtmlPath,
|
|
388
|
+
let indexHtml = await fs.readFile(rootIndexHtmlPath, "utf8");
|
|
312
389
|
indexHtml = indexHtml.replace(/{{APP_NAME}}/g, appName);
|
|
313
390
|
await fs.writeFile(rootIndexHtmlPath, indexHtml);
|
|
314
391
|
}
|
|
315
392
|
}
|
|
316
393
|
|
|
317
394
|
async function detectPackageManager(preferredManager) {
|
|
318
|
-
if (preferredManager !==
|
|
395
|
+
if (preferredManager !== "auto") {
|
|
319
396
|
// Validate the preferred manager is available
|
|
320
397
|
try {
|
|
321
|
-
execSync(`${preferredManager} --version`, { stdio:
|
|
398
|
+
execSync(`${preferredManager} --version`, { stdio: "ignore" });
|
|
322
399
|
return preferredManager;
|
|
323
400
|
} catch {
|
|
324
|
-
console.log(
|
|
401
|
+
console.log(
|
|
402
|
+
chalk.yellow(
|
|
403
|
+
`Warning: ${preferredManager} not found, falling back to auto-detection`
|
|
404
|
+
)
|
|
405
|
+
);
|
|
325
406
|
}
|
|
326
407
|
}
|
|
327
408
|
|
|
328
409
|
// Auto-detect with preference order: pnpm > yarn > npm
|
|
329
|
-
const managers = [
|
|
330
|
-
|
|
410
|
+
const managers = ["pnpm", "yarn", "npm"];
|
|
411
|
+
|
|
331
412
|
for (const manager of managers) {
|
|
332
413
|
try {
|
|
333
|
-
execSync(`${manager} --version`, { stdio:
|
|
414
|
+
execSync(`${manager} --version`, { stdio: "ignore" });
|
|
334
415
|
return manager;
|
|
335
416
|
} catch {
|
|
336
417
|
// Manager not available, try next
|
|
337
418
|
}
|
|
338
419
|
}
|
|
339
|
-
|
|
420
|
+
|
|
340
421
|
// Fallback to npm (should always be available)
|
|
341
|
-
return
|
|
422
|
+
return "npm";
|
|
342
423
|
}
|
|
343
424
|
|
|
344
425
|
async function installDependencies(targetDir, packageManager) {
|
|
345
426
|
try {
|
|
346
427
|
// Change to target directory and install
|
|
347
428
|
process.chdir(targetDir);
|
|
348
|
-
|
|
349
|
-
const installCommand =
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
429
|
+
|
|
430
|
+
const installCommand =
|
|
431
|
+
packageManager === "yarn"
|
|
432
|
+
? "yarn install"
|
|
433
|
+
: packageManager === "pnpm"
|
|
434
|
+
? "pnpm install"
|
|
435
|
+
: "npm install";
|
|
436
|
+
|
|
437
|
+
execSync(installCommand, { stdio: "inherit" });
|
|
355
438
|
} catch (error) {
|
|
356
|
-
throw new Error(
|
|
439
|
+
throw new Error(
|
|
440
|
+
`Failed to install dependencies with ${packageManager}: ${error.message}`
|
|
441
|
+
);
|
|
357
442
|
}
|
|
358
443
|
}
|
|
359
444
|
|
|
360
445
|
async function initializeGit(targetDir, appName) {
|
|
361
446
|
try {
|
|
362
447
|
process.chdir(targetDir);
|
|
363
|
-
|
|
448
|
+
|
|
364
449
|
// Initialize git repository
|
|
365
|
-
execSync(
|
|
366
|
-
|
|
450
|
+
execSync("git init", { stdio: "ignore" });
|
|
451
|
+
|
|
367
452
|
// Create initial commit
|
|
368
|
-
execSync(
|
|
369
|
-
execSync(`git commit -m "Initial commit: ${appName}"`, { stdio:
|
|
370
|
-
|
|
453
|
+
execSync("git add .", { stdio: "ignore" });
|
|
454
|
+
execSync(`git commit -m "Initial commit: ${appName}"`, { stdio: "ignore" });
|
|
455
|
+
// Create a .gitignore file if it does not exist
|
|
456
|
+
const gitignoreContent = `
|
|
457
|
+
node_modules
|
|
458
|
+
dist
|
|
459
|
+
build
|
|
460
|
+
.env
|
|
461
|
+
.next
|
|
462
|
+
.cache
|
|
463
|
+
coverage
|
|
464
|
+
.DS_Store
|
|
465
|
+
npm-debug.log*
|
|
466
|
+
yarn-debug.log*
|
|
467
|
+
yarn-error.log*
|
|
468
|
+
pnpm-debug.log*
|
|
469
|
+
`;
|
|
470
|
+
|
|
471
|
+
const gitignorePath = path.join(targetDir, ".gitignore");
|
|
472
|
+
if (!fs.existsSync(gitignorePath)) {
|
|
473
|
+
fs.writeFileSync(gitignorePath, gitignoreContent.trimStart());
|
|
474
|
+
execSync("git add .gitignore", { stdio: "ignore" });
|
|
475
|
+
}
|
|
371
476
|
} catch (error) {
|
|
372
477
|
// Git initialization is optional, don't fail the whole process
|
|
373
|
-
console.log(chalk.yellow(
|
|
478
|
+
console.log(chalk.yellow("Warning: Failed to initialize git repository"));
|
|
374
479
|
}
|
|
375
480
|
}
|
|
376
481
|
|