@codefast/cli 0.3.1-canary.5 → 0.3.1-canary.8

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/index.js CHANGED
@@ -1,57 +1,33 @@
1
1
  #!/usr/bin/env node
2
2
  import * as __WEBPACK_EXTERNAL_MODULE_commander__ from "commander";
3
- import * as __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__ from "node:child_process";
4
3
  import * as __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__ from "node:fs";
5
4
  import * as __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__ from "node:path";
5
+ import * as __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__ from "node:child_process";
6
6
  import * as __WEBPACK_EXTERNAL_MODULE_node_readline_91c31510__ from "node:readline";
7
7
  import * as __WEBPACK_EXTERNAL_MODULE_glob__ from "glob";
8
8
  import * as __WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__ from "ts-morph";
9
9
  import * as __WEBPACK_EXTERNAL_MODULE_lodash_es_18c59938__ from "lodash-es";
10
10
  import * as __WEBPACK_EXTERNAL_MODULE_zod__ from "zod";
11
11
  import * as __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__ from "node:url";
12
- const MAIN_DEPENDENCIES = [
13
- "@codefast/ui",
14
- "@codefast/hooks"
15
- ];
16
- const DEV_DEPENDENCIES = {
17
- commitLint: [
18
- "@commitlint/cli",
19
- "@commitlint/config-conventional",
20
- "@commitlint/types"
21
- ],
22
- gitTools: [
23
- "simple-git-hooks"
24
- ],
25
- formatting: [
26
- "prettier",
27
- "prettier-plugin-packagejson",
28
- "prettier-plugin-tailwindcss",
29
- "lint-staged"
30
- ],
31
- linting: [
32
- "@codefast/eslint-config"
33
- ]
34
- };
35
- const rl = __WEBPACK_EXTERNAL_MODULE_node_readline_91c31510__.createInterface({
12
+ const rl = __WEBPACK_EXTERNAL_MODULE_node_readline_91c31510__["default"].createInterface({
36
13
  input: process.stdin,
37
14
  output: process.stdout
38
15
  });
39
- function create_project_prompt(question) {
16
+ function utils_prompt(question) {
40
17
  return new Promise((resolve)=>{
41
18
  rl.question(question, (answer)=>{
42
19
  resolve(answer.trim());
43
20
  });
44
21
  });
45
22
  }
46
- function checkEnvironment() {
47
- try {
48
- (0, __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__.execSync)("pnpm --version", {
49
- stdio: "ignore"
50
- });
51
- } catch {
52
- console.error("❌ PNPM chưa được cài đặt. Vui lòng cài đặt PNPM trước.");
53
- process.exit(1);
54
- }
23
+ function runCommand(command) {
24
+ (0, __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__.execSync)(command, {
25
+ stdio: "inherit"
26
+ });
27
+ }
28
+ function writeConfigFile(filePath, content) {
29
+ __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(filePath, content);
30
+ console.log(`📝 Created ${filePath}`);
55
31
  }
56
32
  function validateProjectName(name) {
57
33
  if (!name || /^\s*$/.test(name)) return {
@@ -76,13 +52,13 @@ function validateProjectName(name) {
76
52
  valid: false,
77
53
  error: `Project name "${name}" is a reserved system name.`
78
54
  };
79
- const fullPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.resolve(process.cwd(), name);
80
- if (__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.existsSync(fullPath)) return {
55
+ const fullPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].resolve(process.cwd(), name);
56
+ if (__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(fullPath)) return {
81
57
  valid: false,
82
58
  error: `A directory named "${name}" already exists.`
83
59
  };
84
60
  try {
85
- __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.accessSync(process.cwd(), __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.constants.W_OK);
61
+ __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].accessSync(process.cwd(), __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].constants.W_OK);
86
62
  } catch {
87
63
  return {
88
64
  valid: false,
@@ -94,49 +70,139 @@ function validateProjectName(name) {
94
70
  };
95
71
  }
96
72
  async function getValidProjectName(initialName, attempts = 0, maxAttempts = 3) {
97
- const projectName = initialName ?? await create_project_prompt("Enter project name: ");
73
+ const projectName = initialName ?? await utils_prompt("Enter project name: ");
98
74
  const validation = validateProjectName(projectName);
99
75
  if (validation.valid) return projectName;
100
- if (attempts >= maxAttempts - 1) throw new Error("❌ Exceeded maximum attempts to enter a valid project name.");
76
+ if (attempts >= maxAttempts - 1) throw new Error(`❌ Exceeded maximum attempts to enter a valid project name.`);
101
77
  console.error(`❌ ${validation.error} (${maxAttempts - attempts - 1} attempts remaining)`);
102
78
  return getValidProjectName(void 0, attempts + 1, maxAttempts);
103
79
  }
104
- function runCommand(command) {
105
- (0, __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__.execSync)(command, {
106
- stdio: "inherit"
107
- });
108
- }
109
- function writeConfigFile(filePath, content) {
110
- __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.writeFileSync(filePath, content);
111
- console.log(`📝 Created ${filePath}`);
112
- }
113
- function updatePostcssConfig(projectDir) {
114
- const postcssConfigPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join(projectDir, "postcss.config.mjs");
115
- if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.existsSync(postcssConfigPath)) return void console.warn("⚠️ postcss.config.mjs not found, skipping update.");
116
- let content = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.readFileSync(postcssConfigPath, "utf8");
117
- const typeComment = `/** @type {import('postcss-load-config').Config} */\n`;
118
- if (content.includes(typeComment)) console.log("📝 postcss.config.mjs already contains type comment, no changes made.");
119
- else {
120
- content = content.replace("const config = {", `${typeComment}const config = {`);
121
- __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.writeFileSync(postcssConfigPath, content);
122
- console.log("📝 Updated postcss.config.mjs with type comment.");
80
+ async function checkExistingProject(projectNameArg) {
81
+ const packageJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(process.cwd(), "package.json");
82
+ const packageJsonExists = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(packageJsonPath);
83
+ if (packageJsonExists) {
84
+ console.log(`⚠️ A package.json file has been detected in the current directory.`);
85
+ const confirm = await utils_prompt("Do you want to continue configuring this existing project? [Y/n]: ");
86
+ if ("" === confirm || "y" === confirm.toLowerCase()) {
87
+ const packageJson = JSON.parse(__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(packageJsonPath, "utf8"));
88
+ const projectName = packageJson.name ?? await getValidProjectName(projectNameArg);
89
+ return {
90
+ projectName,
91
+ packageJsonExists
92
+ };
93
+ }
94
+ console.log("Aborting...");
95
+ throw new Error("User aborted the operation.");
123
96
  }
97
+ const projectName = await getValidProjectName(projectNameArg);
98
+ return {
99
+ projectName,
100
+ packageJsonExists
101
+ };
124
102
  }
125
- const configFiles = {
126
- "commitlint.config.mjs": `/**
127
- * @see https://commitlint.js.org/reference/configuration.html
128
- * @type {import('@commitlint/types').UserConfig}
129
- */
130
- const config = {
131
- extends: ["@commitlint/config-conventional"],
132
- rules: {
133
- "body-max-line-length": [2, "always", 350],
134
- },
103
+ const MAIN_DEPENDENCIES = [
104
+ "@codefast/ui",
105
+ "@codefast/hooks"
106
+ ];
107
+ const DEV_DEPENDENCIES = {
108
+ commitLint: [
109
+ "@commitlint/cli",
110
+ "@commitlint/config-conventional",
111
+ "@commitlint/types"
112
+ ],
113
+ gitTools: [
114
+ "simple-git-hooks"
115
+ ],
116
+ formatting: [
117
+ "prettier",
118
+ "prettier-plugin-packagejson",
119
+ "prettier-plugin-tailwindcss",
120
+ "lint-staged"
121
+ ],
122
+ linting: [
123
+ "@codefast/eslint-config"
124
+ ]
135
125
  };
136
-
137
- export default config;
126
+ const PACKAGES_TO_REMOVE = [
127
+ "@eslint/eslintrc"
128
+ ];
129
+ const configGroups = {
130
+ deployment: [
131
+ {
132
+ path: ".vercelignore",
133
+ content: `#-------------------------------------------------------------------------------
134
+ # Dependencies and package managers
135
+ #-------------------------------------------------------------------------------
136
+
137
+ # Node dependencies
138
+ node_modules
139
+ .pnpm-store
140
+ .yarn
141
+
142
+ #-------------------------------------------------------------------------------
143
+ # Development and environment
144
+ #-------------------------------------------------------------------------------
145
+
146
+ # Environment variables (except examples)
147
+ .env*
148
+ !.env.example
149
+
150
+ # Build artifacts
151
+ .next
152
+ build
153
+ dist
154
+ .git
155
+ .github
156
+ .turbo
157
+ .changeset
158
+ .eslintcache
159
+
160
+ # Debug logs
161
+ npm-debug.log*
162
+ yarn-debug.log*
163
+
164
+ #-------------------------------------------------------------------------------
165
+ # Testing
166
+ #-------------------------------------------------------------------------------
167
+
168
+ # Test coverage reports and config snapshots
169
+ coverage
170
+ *.test.*
171
+ *.e2e.*
172
+
173
+ #-------------------------------------------------------------------------------
174
+ # Editor and IDE configuration
175
+ #-------------------------------------------------------------------------------
176
+
177
+ # IDE project files
178
+ .idea
179
+ *.suo
180
+ *.ntvs*
181
+ *.njsproj
182
+ *.sln
183
+
184
+ #-------------------------------------------------------------------------------
185
+ # Operating system files
186
+ #-------------------------------------------------------------------------------
187
+
188
+ # System metadata files
189
+ .DS_Store
190
+ Thumbs.db
191
+
192
+ #-------------------------------------------------------------------------------
193
+ # Deployment
194
+ #-------------------------------------------------------------------------------
195
+
196
+ # Vercel deployment configuration
197
+ .vercel
138
198
  `,
139
- "prettier.config.mjs": `/**
199
+ description: "Ignore files that should not be deployed to Vercel"
200
+ }
201
+ ],
202
+ formatting: [
203
+ {
204
+ path: "prettier.config.mjs",
205
+ content: `/**
140
206
  * @see https://prettier.io/docs/en/configuration.html
141
207
  * @type {import('prettier').Config}
142
208
  */
@@ -149,8 +215,71 @@ const config = {
149
215
 
150
216
  export default config;
151
217
  `,
152
- "lint-staged.config.mjs": `import { relative } from "node:path";
218
+ description: "Prettier configuration for source code formatting"
219
+ },
220
+ {
221
+ path: ".editorconfig",
222
+ content: `# https://editorconfig.org
223
+ root = true
224
+
225
+ [*]
226
+ charset = utf-8
227
+ insert_final_newline = true
228
+
229
+ end_of_line = lf
230
+ indent_style = space
231
+ indent_size = 2
232
+ max_line_length = 120
233
+
234
+ trim_trailing_whitespace = true
235
+
236
+ [Makefile]
237
+ indent_style = tab
238
+
239
+ [{go.mod,go.sum,*.go}]
240
+ indent_style = tab
153
241
 
242
+ [*.rs]
243
+ # Keep in sync with rustfmt
244
+ indent_size = 4
245
+ `,
246
+ description: "Editor configuration for source code formatting"
247
+ }
248
+ ],
249
+ linting: [
250
+ {
251
+ path: "commitlint.config.mjs",
252
+ content: `/**
253
+ * @see https://commitlint.js.org/reference/configuration.html
254
+ * @type {import('@commitlint/types').UserConfig}
255
+ */
256
+ const config = {
257
+ extends: ["@commitlint/config-conventional"],
258
+ rules: {
259
+ "body-max-line-length": [2, "always", 350],
260
+ },
261
+ };
262
+
263
+ export default config;
264
+ `,
265
+ description: "Commitlint configuration"
266
+ },
267
+ {
268
+ path: "eslint.config.mjs",
269
+ content: `import { config } from "@codefast/eslint-config/next";
270
+ /**
271
+ * @see https://eslint.org/docs/latest/use/configure/configuration-files
272
+ * @type {import('eslint').Linter.Config[]}
273
+ */
274
+ const eslintConfig = [...config];
275
+
276
+ export default eslintConfig;
277
+ `,
278
+ description: "ESLint configuration for the project"
279
+ },
280
+ {
281
+ path: "lint-staged.config.mjs",
282
+ content: `import { relative } from "node:path";
154
283
  /**
155
284
  * Builds an ESLint command with the given filenames.
156
285
  *
@@ -174,16 +303,13 @@ const config = {
174
303
 
175
304
  export default config;
176
305
  `,
177
- "eslint.config.mjs": `import { config } from "@codefast/eslint-config/next";
178
- /**
179
- * @see https://eslint.org/docs/latest/use/configure/configuration-files
180
- * @type {import('eslint').Linter.Config[]}
181
- */
182
- const eslintConfig = [...config];
183
-
184
- export default eslintConfig;
185
- `,
186
- "src/lib/fonts.ts": `import { cn } from "@codefast/ui";
306
+ description: "Configure lint-staged for pre-commit checks"
307
+ }
308
+ ],
309
+ styles: [
310
+ {
311
+ path: "src/lib/fonts.ts",
312
+ content: `import { cn } from "@codefast/ui";
187
313
  import { Geist, Geist_Mono as GeistMono } from "next/font/google";
188
314
 
189
315
  const fontGeistSans = Geist({
@@ -198,7 +324,11 @@ const fontGeistMono = GeistMono({
198
324
 
199
325
  export const fontVariables = cn(fontGeistSans.variable, fontGeistMono.variable);
200
326
  `,
201
- "src/app/globals.css": `@import "tailwindcss";
327
+ description: "Font configuration for the application"
328
+ },
329
+ {
330
+ path: "src/app/globals.css",
331
+ content: `@import "tailwindcss";
202
332
 
203
333
  @import "@codefast/ui/styles.css";
204
334
 
@@ -206,103 +336,71 @@ export const fontVariables = cn(fontGeistSans.variable, fontGeistMono.variable);
206
336
 
207
337
  @custom-variant dark (&:where(.dark, .dark *));
208
338
 
209
- @theme inline {
210
- --font-sans: var(--font-geist-sans);
211
- --font-mono: var(--font-geist-mono);
212
- }
213
-
214
339
  @layer base {
215
340
  :root {
341
+ --font-sans: var(--font-geist-sans);
342
+ --font-mono: var(--font-geist-mono);
216
343
  --input: var(--color-neutral-200);
217
344
  --border: var(--color-neutral-200);
218
-
219
345
  --ring: var(--color-neutral-400);
220
-
221
346
  --background: var(--color-white);
222
347
  --foreground: var(--color-neutral-950);
223
-
224
348
  --primary: var(--color-sky-500);
225
349
  --primary-foreground: var(--color-neutral-50);
226
-
227
350
  --secondary: var(--color-neutral-100);
228
351
  --secondary-foreground: var(--color-neutral-900);
229
-
230
352
  --destructive: var(--color-red-600);
231
-
232
353
  --accent: var(--color-neutral-100);
233
354
  --accent-foreground: var(--color-neutral-900);
234
-
235
355
  --muted: var(--color-neutral-100);
236
356
  --muted-foreground: var(--color-neutral-500);
237
-
238
357
  --popover: var(--color-white);
239
358
  --popover-foreground: var(--color-neutral-950);
240
359
  --popover-overlay: --alpha(var(--color-neutral-900) / 20%);
241
-
242
360
  --card: var(--color-white);
243
361
  --card-foreground: var(--color-neutral-950);
244
-
245
362
  --sidebar: var(--color-neutral-50);
246
363
  --sidebar-foreground: var(--color-neutral-950);
247
-
248
364
  --sidebar-primary: var(--color-sky-500);
249
365
  --sidebar-primary-foreground: var(--color-neutral-50);
250
-
251
366
  --sidebar-accent: var(--color-neutral-100);
252
367
  --sidebar-accent-foreground: var(--color-neutral-900);
253
-
254
368
  --sidebar-border: var(--color-neutral-200);
255
369
  --sidebar-ring: var(--color-neutral-400);
256
-
257
370
  --chart-1: var(--color-orange-600);
258
371
  --chart-2: var(--color-teal-600);
259
372
  --chart-3: var(--color-cyan-600);
260
373
  --chart-4: var(--color-amber-600);
261
374
  --chart-5: var(--color-amber-500);
262
375
  }
263
-
264
376
  @variant dark {
265
377
  --input: var(--color-neutral-700);
266
378
  --border: --alpha(var(--color-neutral-700) / 50%);
267
-
268
379
  --ring: var(--color-neutral-500);
269
-
270
380
  --background: var(--color-neutral-950);
271
381
  --foreground: var(--color-neutral-50);
272
-
273
382
  --primary: var(--color-sky-700);
274
383
  --primary-foreground: var(--color-neutral-50);
275
-
276
384
  --secondary: var(--color-neutral-800);
277
385
  --secondary-foreground: var(--color-neutral-50);
278
-
279
386
  --destructive: var(--color-red-400);
280
-
281
387
  --accent: var(--color-neutral-700);
282
388
  --accent-foreground: var(--color-neutral-50);
283
-
284
389
  --muted: var(--color-neutral-800);
285
390
  --muted-foreground: var(--color-neutral-400);
286
-
287
391
  --popover: var(--color-neutral-800);
288
392
  --popover-foreground: var(--color-neutral-50);
289
393
  --popover-overlay: --alpha(var(--color-neutral-900) / 80%);
290
-
291
394
  --card: var(--color-neutral-900);
292
395
  --card-foreground: var(--color-neutral-50);
293
-
294
396
  --sidebar: var(--color-neutral-900);
295
397
  --sidebar-foreground: var(--color-neutral-50);
296
-
297
398
  --sidebar-primary: var(--color-sky-700);
298
399
  --sidebar-primary-foreground: var(--color-neutral-50);
299
-
300
400
  --sidebar-accent: var(--color-neutral-800);
301
401
  --sidebar-accent-foreground: var(--color-neutral-50);
302
-
303
402
  --sidebar-border: var(--color-neutral-800);
304
403
  --sidebar-ring: var(--color-neutral-600);
305
-
306
404
  --chart-1: var(--color-blue-700);
307
405
  --chart-2: var(--color-emerald-500);
308
406
  --chart-3: var(--color-amber-500);
@@ -310,82 +408,164 @@ export const fontVariables = cn(fontGeistSans.variable, fontGeistMono.variable);
310
408
  --chart-5: var(--color-rose-500);
311
409
  }
312
410
  }
313
- `
411
+ `,
412
+ description: "Global CSS variables for the application"
413
+ }
414
+ ]
314
415
  };
416
+ function updatePostcssConfig(projectDir) {
417
+ const postcssConfigPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, "postcss.config.mjs");
418
+ if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(postcssConfigPath)) return void console.warn(`⚠️ postcss.config.mjs not found, skipping update.`);
419
+ let content = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(postcssConfigPath, "utf8");
420
+ const typeComment = `/** @type {import('postcss-load-config').Config} */\n`;
421
+ if (content.includes(typeComment)) console.log(`📝 postcss.config.mjs already contains type comment, no changes made.`);
422
+ else {
423
+ content = content.replace("const config = {", `${typeComment}const config = {`);
424
+ __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(postcssConfigPath, content);
425
+ console.log(`📝 Updated postcss.config.mjs with type comment.`);
426
+ }
427
+ }
428
+ function updateLayoutFile(projectDir) {
429
+ const layoutPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, "src/app/layout.tsx");
430
+ if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(layoutPath)) return void console.warn(`⚠️ src/app/layout.tsx not found, skipping update.`);
431
+ let content = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(layoutPath, "utf8");
432
+ if (content.includes('<html className={cn(fontVariables, "antialiased")} lang="en">')) return void console.log(`📝 src/app/layout.tsx already uses fontVariables in html tag, no changes made.`);
433
+ const newImports = `import type { Metadata } from "next";
434
+
435
+ import { cn } from "@codefast/ui";
436
+
437
+ import { fontVariables } from "@/lib/fonts";
438
+ import "@/app/globals.css";`;
439
+ content = content.replaceAll(/import\s+{[^}]+}\s+from\s+["']next\/font\/google["'];\s*/g, "");
440
+ content = content.replace(/const\s+geistSans\s*=[^;]+;\s*const\s+geistMono\s*=[^;]+;\s*/, "");
441
+ content = content.replace(/import\s+type\s+{[^}]+}\s+from\s+["']next["'];\s*import\s+["']\.\/globals\.css["'];\s*/, newImports);
442
+ const htmlRegex = /<html\s+lang="en"\s*>/;
443
+ const newHtml = '<html className={cn(fontVariables, "antialiased")} lang="en">';
444
+ content = content.replace(htmlRegex, newHtml);
445
+ const bodyRegex = /<body\s+className={`[^`]*`}\s*>/;
446
+ const newBody = "<body>";
447
+ content = content.replace(bodyRegex, newBody);
448
+ try {
449
+ __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(layoutPath, content);
450
+ console.log(`📝 Updated src/app/layout.tsx to use fontVariables in html tag and removed className from body`);
451
+ } catch (error) {
452
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
453
+ console.warn(`⚠️ Failed to update src/app/layout.tsx: ${errorMessage}`);
454
+ }
455
+ }
315
456
  function updatePackageJson(projectDir) {
316
- const packageJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join(projectDir, "package.json");
317
- const packageJson = JSON.parse(__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.readFileSync(packageJsonPath, "utf8"));
457
+ const packageJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, "package.json");
458
+ const packageJson = JSON.parse(__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(packageJsonPath, "utf8"));
318
459
  packageJson.scripts = {
319
460
  ...packageJson.scripts,
461
+ "deploy:preview": "vercel deploy --archive=tgz",
462
+ "deploy:prod": "vercel deploy --archive=tgz --prod",
320
463
  format: 'prettier --write "**/*.{js,mjs,jsx,ts,tsx,json,css,md,mdx}"',
321
464
  "format:check": 'prettier --check "**/*.{js,mjs,jsx,ts,tsx,json,css,md,mdx}"',
322
- "lint:check": "next lint --max-warnings 0"
465
+ lint: "next lint --fix --max-warnings 0",
466
+ "lint:check": "next lint --max-warnings 0",
467
+ "package:install": "pnpm install",
468
+ "package:outdated": "pnpm outdated",
469
+ "package:upgrade": "pnpm update --latest",
470
+ preview: "pnpm build && pnpm start"
323
471
  };
324
472
  packageJson["simple-git-hooks"] = {
325
473
  "pre-commit": "pnpm lint-staged",
326
474
  "commit-msg": "pnpm commitlint --edit"
327
475
  };
328
- __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
329
- console.log("📝 Updated package.json");
476
+ __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
477
+ console.log(`📝 Updated package.json`);
330
478
  }
331
- function createNextProject(projectName) {
332
- console.log("📦 Creating Next.js project...");
333
- const flags = '--ts --tailwind --eslint --app --turbo --use-pnpm --src-dir --turbopack --import-alias "@/*"';
334
- runCommand(`npx create-next-app@latest ${projectName} ${flags}`);
479
+ function createConfigFiles(projectDir) {
480
+ console.log(`\n📝 Creating configuration files...`);
481
+ for (const [category, configs] of Object.entries(configGroups)){
482
+ console.log(`\n📂 Setting up ${category} configurations:`);
483
+ for (const { path: filePath, content, description } of configs){
484
+ const fullPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, filePath);
485
+ const dir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(fullPath);
486
+ if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(dir)) __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].mkdirSync(dir, {
487
+ recursive: true
488
+ });
489
+ writeConfigFile(fullPath, content);
490
+ if (description) console.log(` ℹ️ ${filePath}: ${description}`);
491
+ }
492
+ }
335
493
  }
336
494
  function installDependencies() {
337
- console.log("📚 Installing dependencies...");
495
+ console.log(`\n📚 Installing dependencies...`);
338
496
  if (MAIN_DEPENDENCIES.length > 0) runCommand(`pnpm add ${MAIN_DEPENDENCIES.join(" ")}`);
339
497
  const allDevDependencies = Object.values(DEV_DEPENDENCIES).flat().join(" ");
340
498
  if (allDevDependencies) runCommand(`pnpm add -D ${allDevDependencies}`);
341
499
  }
342
- function createConfigFiles(projectDir) {
343
- console.log(`\n📝 Creating configuration files...`);
344
- for (const [filePath, content] of Object.entries(configFiles)){
345
- const fullPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join(projectDir, filePath);
346
- const dir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.dirname(fullPath);
347
- if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.existsSync(dir)) __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.mkdirSync(dir, {
348
- recursive: true
500
+ function cleanupPackages() {
501
+ console.log(`\n🧹 Cleaning up unnecessary packages...`);
502
+ const packageJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join(process.cwd(), "package.json");
503
+ if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.existsSync(packageJsonPath)) return void console.warn(`⚠️ package.json not found, skipping cleanup.`);
504
+ let packageJson;
505
+ try {
506
+ packageJson = JSON.parse(__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.readFileSync(packageJsonPath, "utf8"));
507
+ } catch (error) {
508
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
509
+ console.warn(`⚠️ Error reading package.json: ${errorMessage}, skipping cleanup.`);
510
+ return;
511
+ }
512
+ const dependencies = packageJson.dependencies ?? {};
513
+ const devDependencies = packageJson.devDependencies ?? {};
514
+ const packagesToRemove = PACKAGES_TO_REMOVE.filter((pkg)=>pkg in dependencies || pkg in devDependencies);
515
+ if (packagesToRemove.length > 0) runCommand(`pnpm remove ${packagesToRemove.join(" ")}`);
516
+ else console.log(`ℹ️ No unnecessary packages found in package.json to remove.`);
517
+ }
518
+ function checkEnvironment() {
519
+ try {
520
+ (0, __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__.execSync)("pnpm --version", {
521
+ stdio: "ignore"
349
522
  });
350
- writeConfigFile(fullPath, content);
523
+ } catch {
524
+ console.error(`❌ PNPM chưa được cài đặt. Vui lòng cài đặt PNPM trước.`);
525
+ process.exit(1);
351
526
  }
352
527
  }
528
+ function createNextProject(projectName) {
529
+ console.log(`📦 Creating Next.js project...`);
530
+ const flags = '--ts --tailwind --eslint --app --turbo --use-pnpm --src-dir --turbopack --import-alias "@/*"';
531
+ runCommand(`npx create-next-app@latest ${projectName} ${flags}`);
532
+ }
353
533
  function createProjectCommand(program) {
354
534
  program.command("create-project [name]").description("Create a new Next.js project with recommended setup").action(async (projectNameArg)=>{
355
535
  try {
356
536
  checkEnvironment();
357
- const projectName = await getValidProjectName(projectNameArg);
358
- console.log(`\n🚀 Starting project creation for ${projectName}...\n`);
359
- const packageJsonExists = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.existsSync(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join(process.cwd(), "package.json"));
360
- if (packageJsonExists) console.log(`📦 A package.json file has been detected. Skipping the Next.js project creation step.`);
361
- else {
537
+ const { projectName, packageJsonExists } = await checkExistingProject(projectNameArg);
538
+ if (!packageJsonExists) {
539
+ console.log(`\n🚀 Starting project creation for ${projectName}...\n`);
362
540
  createNextProject(projectName);
363
541
  process.chdir(projectName);
364
542
  console.log(`📂 Moved to ${projectName}`);
365
543
  }
544
+ updateLayoutFile(process.cwd());
366
545
  updatePostcssConfig(process.cwd());
367
546
  installDependencies();
547
+ cleanupPackages();
368
548
  createConfigFiles(process.cwd());
369
549
  updatePackageJson(process.cwd());
370
550
  console.log(`\n🔄 Activating git hooks...`);
371
551
  runCommand("pnpm simple-git-hooks");
372
552
  console.log(`\n📝 Formatting files with Prettier...`);
373
553
  runCommand("pnpm format");
374
- console.log(`\n✅ Project created successfully!`);
554
+ console.log(`\n✅ Project ${packageJsonExists ? "configured" : "created"} successfully!`);
375
555
  console.log(`- Project: ${projectName}`);
376
556
  console.log("- Next.js with TypeScript");
377
557
  console.log("- TailwindCSS and @codefast/ui");
378
558
  console.log("- ESLint, Prettier, Commitlint, and Git Hooks");
379
559
  console.log("- Lint-staged for pre-commit checks");
380
- console.log(`\n📁 Project directory: ${__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.resolve(process.cwd())}`);
560
+ console.log(`\n📁 Project directory: ${process.cwd()}`);
381
561
  console.log(`\n🚀 To start development:`);
382
562
  console.log(`cd ${projectName} && pnpm dev`);
383
- rl.close();
384
563
  } catch (error) {
385
564
  const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
386
565
  console.error(`\n❌ An error occurred: ${errorMessage}`);
387
- rl.close();
388
566
  process.exit(1);
567
+ } finally{
568
+ rl.close();
389
569
  }
390
570
  });
391
571
  }