@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/CHANGELOG.md +24 -0
- package/dist/index.cjs +327 -146
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +326 -146
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
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
|
|
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
|
|
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
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
|
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(
|
|
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
|
|
105
|
-
(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
|
126
|
-
"
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
332
|
-
console.log(
|
|
333
|
-
const
|
|
334
|
-
|
|
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(
|
|
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
|
|
343
|
-
console.log(`\n
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
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
|
-
|
|
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
|
|
358
|
-
|
|
359
|
-
|
|
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: ${
|
|
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
|
}
|